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
|
Cluster: clusterBar
|
||||||
ephemeral:
|
ephemeral:
|
||||||
bootstrapInfo: ""
|
|
||||||
clusterKubeconf: clusterBar_ephemeral
|
clusterKubeconf: clusterBar_ephemeral
|
||||||
managementConfiguration: ""
|
managementConfiguration: ""
|
||||||
|
|
||||||
@ -10,7 +9,6 @@ server: ""
|
|||||||
|
|
||||||
Cluster: clusterBar
|
Cluster: clusterBar
|
||||||
target:
|
target:
|
||||||
bootstrapInfo: ""
|
|
||||||
clusterKubeconf: clusterBar_target
|
clusterKubeconf: clusterBar_target
|
||||||
managementConfiguration: ""
|
managementConfiguration: ""
|
||||||
|
|
||||||
@ -20,7 +18,6 @@ server: ""
|
|||||||
|
|
||||||
Cluster: clusterBaz
|
Cluster: clusterBaz
|
||||||
ephemeral:
|
ephemeral:
|
||||||
bootstrapInfo: ""
|
|
||||||
clusterKubeconf: clusterBaz_ephemeral
|
clusterKubeconf: clusterBaz_ephemeral
|
||||||
managementConfiguration: ""
|
managementConfiguration: ""
|
||||||
|
|
||||||
@ -30,7 +27,6 @@ server: ""
|
|||||||
|
|
||||||
Cluster: clusterBaz
|
Cluster: clusterBaz
|
||||||
target:
|
target:
|
||||||
bootstrapInfo: ""
|
|
||||||
clusterKubeconf: clusterBaz_target
|
clusterKubeconf: clusterBaz_target
|
||||||
managementConfiguration: ""
|
managementConfiguration: ""
|
||||||
|
|
||||||
@ -40,7 +36,6 @@ server: ""
|
|||||||
|
|
||||||
Cluster: clusterFoo
|
Cluster: clusterFoo
|
||||||
ephemeral:
|
ephemeral:
|
||||||
bootstrapInfo: ""
|
|
||||||
clusterKubeconf: clusterFoo_ephemeral
|
clusterKubeconf: clusterFoo_ephemeral
|
||||||
managementConfiguration: ""
|
managementConfiguration: ""
|
||||||
|
|
||||||
@ -50,7 +45,6 @@ server: ""
|
|||||||
|
|
||||||
Cluster: clusterFoo
|
Cluster: clusterFoo
|
||||||
target:
|
target:
|
||||||
bootstrapInfo: ""
|
|
||||||
clusterKubeconf: clusterFoo_target
|
clusterKubeconf: clusterFoo_target
|
||||||
managementConfiguration: ""
|
managementConfiguration: ""
|
||||||
|
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
Cluster: clusterBar
|
Cluster: clusterBar
|
||||||
ephemeral:
|
ephemeral:
|
||||||
bootstrapInfo: ""
|
|
||||||
clusterKubeconf: clusterBar_ephemeral
|
clusterKubeconf: clusterBar_ephemeral
|
||||||
managementConfiguration: ""
|
managementConfiguration: ""
|
||||||
|
|
||||||
@ -10,7 +9,6 @@ server: ""
|
|||||||
|
|
||||||
Cluster: clusterBar
|
Cluster: clusterBar
|
||||||
target:
|
target:
|
||||||
bootstrapInfo: ""
|
|
||||||
clusterKubeconf: clusterBar_target
|
clusterKubeconf: clusterBar_target
|
||||||
managementConfiguration: ""
|
managementConfiguration: ""
|
||||||
|
|
||||||
@ -20,7 +18,6 @@ server: ""
|
|||||||
|
|
||||||
Cluster: clusterBaz
|
Cluster: clusterBaz
|
||||||
ephemeral:
|
ephemeral:
|
||||||
bootstrapInfo: ""
|
|
||||||
clusterKubeconf: clusterBaz_ephemeral
|
clusterKubeconf: clusterBaz_ephemeral
|
||||||
managementConfiguration: ""
|
managementConfiguration: ""
|
||||||
|
|
||||||
@ -30,7 +27,6 @@ server: ""
|
|||||||
|
|
||||||
Cluster: clusterBaz
|
Cluster: clusterBaz
|
||||||
target:
|
target:
|
||||||
bootstrapInfo: ""
|
|
||||||
clusterKubeconf: clusterBaz_target
|
clusterKubeconf: clusterBaz_target
|
||||||
managementConfiguration: ""
|
managementConfiguration: ""
|
||||||
|
|
||||||
@ -40,7 +36,6 @@ server: ""
|
|||||||
|
|
||||||
Cluster: clusterFoo
|
Cluster: clusterFoo
|
||||||
ephemeral:
|
ephemeral:
|
||||||
bootstrapInfo: ""
|
|
||||||
clusterKubeconf: clusterFoo_ephemeral
|
clusterKubeconf: clusterFoo_ephemeral
|
||||||
managementConfiguration: ""
|
managementConfiguration: ""
|
||||||
|
|
||||||
@ -50,7 +45,6 @@ server: ""
|
|||||||
|
|
||||||
Cluster: clusterFoo
|
Cluster: clusterFoo
|
||||||
target:
|
target:
|
||||||
bootstrapInfo: ""
|
|
||||||
clusterKubeconf: clusterFoo_target
|
clusterKubeconf: clusterFoo_target
|
||||||
managementConfiguration: ""
|
managementConfiguration: ""
|
||||||
|
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
Cluster: clusterFoo
|
Cluster: clusterFoo
|
||||||
ephemeral:
|
ephemeral:
|
||||||
bootstrapInfo: ""
|
|
||||||
clusterKubeconf: clusterFoo_ephemeral
|
clusterKubeconf: clusterFoo_ephemeral
|
||||||
managementConfiguration: ""
|
managementConfiguration: ""
|
||||||
|
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
Cluster: clusterBar
|
Cluster: clusterBar
|
||||||
ephemeral:
|
ephemeral:
|
||||||
bootstrapInfo: ""
|
|
||||||
clusterKubeconf: clusterBar_ephemeral
|
clusterKubeconf: clusterBar_ephemeral
|
||||||
managementConfiguration: ""
|
managementConfiguration: ""
|
||||||
|
|
||||||
@ -10,7 +9,6 @@ server: ""
|
|||||||
|
|
||||||
Cluster: clusterBar
|
Cluster: clusterBar
|
||||||
target:
|
target:
|
||||||
bootstrapInfo: ""
|
|
||||||
clusterKubeconf: clusterBar_target
|
clusterKubeconf: clusterBar_target
|
||||||
managementConfiguration: ""
|
managementConfiguration: ""
|
||||||
|
|
||||||
@ -20,7 +18,6 @@ server: ""
|
|||||||
|
|
||||||
Cluster: clusterBaz
|
Cluster: clusterBaz
|
||||||
ephemeral:
|
ephemeral:
|
||||||
bootstrapInfo: ""
|
|
||||||
clusterKubeconf: clusterBaz_ephemeral
|
clusterKubeconf: clusterBaz_ephemeral
|
||||||
managementConfiguration: ""
|
managementConfiguration: ""
|
||||||
|
|
||||||
@ -30,7 +27,6 @@ server: ""
|
|||||||
|
|
||||||
Cluster: clusterBaz
|
Cluster: clusterBaz
|
||||||
target:
|
target:
|
||||||
bootstrapInfo: ""
|
|
||||||
clusterKubeconf: clusterBaz_target
|
clusterKubeconf: clusterBaz_target
|
||||||
managementConfiguration: ""
|
managementConfiguration: ""
|
||||||
|
|
||||||
@ -40,7 +36,6 @@ server: ""
|
|||||||
|
|
||||||
Cluster: clusterFoo
|
Cluster: clusterFoo
|
||||||
ephemeral:
|
ephemeral:
|
||||||
bootstrapInfo: ""
|
|
||||||
clusterKubeconf: clusterFoo_ephemeral
|
clusterKubeconf: clusterFoo_ephemeral
|
||||||
managementConfiguration: ""
|
managementConfiguration: ""
|
||||||
|
|
||||||
@ -50,7 +45,6 @@ server: ""
|
|||||||
|
|
||||||
Cluster: clusterFoo
|
Cluster: clusterFoo
|
||||||
target:
|
target:
|
||||||
bootstrapInfo: ""
|
|
||||||
clusterKubeconf: clusterFoo_target
|
clusterKubeconf: clusterFoo_target
|
||||||
managementConfiguration: ""
|
managementConfiguration: ""
|
||||||
|
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
Cluster: clusterBar
|
Cluster: clusterBar
|
||||||
ephemeral:
|
ephemeral:
|
||||||
bootstrapInfo: ""
|
|
||||||
clusterKubeconf: clusterBar_ephemeral
|
clusterKubeconf: clusterBar_ephemeral
|
||||||
managementConfiguration: ""
|
managementConfiguration: ""
|
||||||
|
|
||||||
@ -10,7 +9,6 @@ server: ""
|
|||||||
|
|
||||||
Cluster: clusterBar
|
Cluster: clusterBar
|
||||||
target:
|
target:
|
||||||
bootstrapInfo: ""
|
|
||||||
clusterKubeconf: clusterBar_target
|
clusterKubeconf: clusterBar_target
|
||||||
managementConfiguration: ""
|
managementConfiguration: ""
|
||||||
|
|
||||||
@ -20,7 +18,6 @@ server: ""
|
|||||||
|
|
||||||
Cluster: clusterBaz
|
Cluster: clusterBaz
|
||||||
ephemeral:
|
ephemeral:
|
||||||
bootstrapInfo: ""
|
|
||||||
clusterKubeconf: clusterBaz_ephemeral
|
clusterKubeconf: clusterBaz_ephemeral
|
||||||
managementConfiguration: ""
|
managementConfiguration: ""
|
||||||
|
|
||||||
@ -30,7 +27,6 @@ server: ""
|
|||||||
|
|
||||||
Cluster: clusterBaz
|
Cluster: clusterBaz
|
||||||
target:
|
target:
|
||||||
bootstrapInfo: ""
|
|
||||||
clusterKubeconf: clusterBaz_target
|
clusterKubeconf: clusterBaz_target
|
||||||
managementConfiguration: ""
|
managementConfiguration: ""
|
||||||
|
|
||||||
@ -40,7 +36,6 @@ server: ""
|
|||||||
|
|
||||||
Cluster: clusterFoo
|
Cluster: clusterFoo
|
||||||
ephemeral:
|
ephemeral:
|
||||||
bootstrapInfo: ""
|
|
||||||
clusterKubeconf: clusterFoo_ephemeral
|
clusterKubeconf: clusterFoo_ephemeral
|
||||||
managementConfiguration: ""
|
managementConfiguration: ""
|
||||||
|
|
||||||
@ -50,7 +45,6 @@ server: ""
|
|||||||
|
|
||||||
Cluster: clusterFoo
|
Cluster: clusterFoo
|
||||||
target:
|
target:
|
||||||
bootstrapInfo: ""
|
|
||||||
clusterKubeconf: clusterFoo_target
|
clusterKubeconf: clusterFoo_target
|
||||||
managementConfiguration: ""
|
managementConfiguration: ""
|
||||||
|
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
Cluster: clusterFoo
|
Cluster: clusterFoo
|
||||||
target:
|
target:
|
||||||
bootstrapInfo: ""
|
|
||||||
clusterKubeconf: clusterFoo_target
|
clusterKubeconf: clusterFoo_target
|
||||||
managementConfiguration: ""
|
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:
|
resources:
|
||||||
- secret.yaml
|
- 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{},
|
&PhasePlan{},
|
||||||
&KubeConfig{},
|
&KubeConfig{},
|
||||||
&KubernetesApply{},
|
&KubernetesApply{},
|
||||||
|
&ImageConfiguration{},
|
||||||
|
&RemoteDirectConfiguration{},
|
||||||
)
|
)
|
||||||
_ = AddToScheme(Scheme) //nolint:errcheck
|
_ = AddToScheme(Scheme) //nolint:errcheck
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,4 @@
|
|||||||
/*
|
/*
|
||||||
Copyright 2014 The Kubernetes Authors.
|
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
you may not use this file except in compliance with the License.
|
||||||
You may obtain a copy of the License at
|
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.
|
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
|
// Container structure contains parameters related to Docker runtime, used for building image
|
||||||
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
|
|
||||||
type Container struct {
|
type Container struct {
|
||||||
// Container volume directory binding.
|
// Container volume directory binding.
|
||||||
Volume string `json:"volume,omitempty"`
|
Volume string `json:"volume,omitempty"`
|
||||||
@ -38,7 +28,7 @@ type Container struct {
|
|||||||
ContainerRuntime string `json:"containerRuntime,omitempty"`
|
ContainerRuntime string `json:"containerRuntime,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// Builder parameters
|
// Builder structure defines metadata files (including Cloud Init metadata) used for image
|
||||||
type Builder struct {
|
type Builder struct {
|
||||||
// Cloud Init user-data file name placed to the container volume root
|
// Cloud Init user-data file name placed to the container volume root
|
||||||
UserDataFileName string `json:"userDataFileName,omitempty"`
|
UserDataFileName string `json:"userDataFileName,omitempty"`
|
||||||
@ -48,35 +38,12 @@ type Builder struct {
|
|||||||
OutputMetadataFileName string `json:"outputMetadataFileName,omitempty"`
|
OutputMetadataFileName string `json:"outputMetadataFileName,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// RemoteDirect configuration options
|
// ImageConfiguration structure is inherited from apimachinery TypeMeta and ObjectMeta and is a top level
|
||||||
type RemoteDirect struct {
|
// configuration structure for building image
|
||||||
// IsoURL specifies url to download ISO image for ephemeral node
|
type ImageConfiguration struct {
|
||||||
IsoURL string `json:"isoUrl,omitempty"`
|
metav1.TypeMeta `json:",inline"`
|
||||||
}
|
metav1.ObjectMeta `json:"metadata,omitempty"`
|
||||||
|
|
||||||
// Bootstrap functions
|
Container *Container `json:"container,omitempty"`
|
||||||
func (b *Bootstrap) String() string {
|
Builder *Builder `json:"builder,omitempty"`
|
||||||
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)
|
|
||||||
}
|
}
|
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)
|
in.DeepCopyInto(out)
|
||||||
return 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"
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
api "opendev.org/airship/airshipctl/pkg/api/v1alpha1"
|
||||||
"opendev.org/airship/airshipctl/pkg/bootstrap/cloudinit"
|
"opendev.org/airship/airshipctl/pkg/bootstrap/cloudinit"
|
||||||
"opendev.org/airship/airshipctl/pkg/config"
|
"opendev.org/airship/airshipctl/pkg/config"
|
||||||
"opendev.org/airship/airshipctl/pkg/container"
|
"opendev.org/airship/airshipctl/pkg/container"
|
||||||
@ -43,17 +44,6 @@ func GenerateBootstrapIso(settings *environment.AirshipCTLSettings) error {
|
|||||||
return err
|
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)
|
root, err := globalConf.CurrentContextEntryPoint(config.BootstrapPhase)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -63,23 +53,41 @@ func GenerateBootstrapIso(settings *environment.AirshipCTLSettings) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Print("Creating ISO builder container")
|
imageConfiguration := &api.ImageConfiguration{}
|
||||||
builder, err := container.NewContainer(
|
selector, err := document.NewSelector().ByObject(imageConfiguration, api.Scheme)
|
||||||
&ctx, cfg.Container.ContainerRuntime,
|
if err != nil {
|
||||||
cfg.Container.Image)
|
return err
|
||||||
|
}
|
||||||
|
doc, err := docBundle.SelectOne(selector)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
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 {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
log.Print("Checking artifacts")
|
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 == "" {
|
if cfg.Container.Volume == "" {
|
||||||
return config.ErrMissingConfig{
|
return config.ErrMissingConfig{
|
||||||
What: "Must specify volume bind for ISO builder container",
|
What: "Must specify volume bind for ISO builder container",
|
||||||
@ -104,19 +112,22 @@ func verifyInputs(cfg *config.Bootstrap) error {
|
|||||||
return nil
|
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]
|
hostVol := strings.Split(cfg.Container.Volume, ":")[0]
|
||||||
|
|
||||||
fls := make(map[string][]byte)
|
fls := make(map[string][]byte)
|
||||||
fls[filepath.Join(hostVol, cfg.Builder.UserDataFileName)] = userData
|
fls[filepath.Join(hostVol, cfg.Builder.UserDataFileName)] = userData
|
||||||
fls[filepath.Join(hostVol, cfg.Builder.NetworkConfigFileName)] = netConf
|
fls[filepath.Join(hostVol, cfg.Builder.NetworkConfigFileName)] = netConf
|
||||||
// TODO (dukov) Get rid of this ugly conversion byte -> string -> byte
|
fls[filepath.Join(hostVol, builderConfigFileName)] = builderCfgYaml
|
||||||
builderData := []byte(cfg.String())
|
|
||||||
fls[filepath.Join(hostVol, builderConfigFileName)] = builderData
|
|
||||||
return fls
|
return fls
|
||||||
}
|
}
|
||||||
|
|
||||||
func verifyArtifacts(cfg *config.Bootstrap) error {
|
func verifyArtifacts(cfg *api.ImageConfiguration) error {
|
||||||
hostVol := strings.Split(cfg.Container.Volume, ":")[0]
|
hostVol := strings.Split(cfg.Container.Volume, ":")[0]
|
||||||
metadataPath := filepath.Join(hostVol, cfg.Builder.OutputMetadataFileName)
|
metadataPath := filepath.Join(hostVol, cfg.Builder.OutputMetadataFileName)
|
||||||
_, err := os.Stat(metadataPath)
|
_, err := os.Stat(metadataPath)
|
||||||
@ -126,7 +137,8 @@ func verifyArtifacts(cfg *config.Bootstrap) error {
|
|||||||
func generateBootstrapIso(
|
func generateBootstrapIso(
|
||||||
docBundle document.Bundle,
|
docBundle document.Bundle,
|
||||||
builder container.Container,
|
builder container.Container,
|
||||||
cfg *config.Bootstrap,
|
doc document.Document,
|
||||||
|
cfg *api.ImageConfiguration,
|
||||||
debug bool,
|
debug bool,
|
||||||
) error {
|
) error {
|
||||||
cntVol := strings.Split(cfg.Container.Volume, ":")[1]
|
cntVol := strings.Split(cfg.Container.Volume, ":")[1]
|
||||||
@ -136,7 +148,12 @@ func generateBootstrapIso(
|
|||||||
return err
|
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 {
|
if err = util.WriteFiles(fls, 0600); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -21,9 +21,12 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"opendev.org/airship/airshipctl/pkg/environment"
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
|
|
||||||
|
api "opendev.org/airship/airshipctl/pkg/api/v1alpha1"
|
||||||
"opendev.org/airship/airshipctl/pkg/config"
|
"opendev.org/airship/airshipctl/pkg/config"
|
||||||
"opendev.org/airship/airshipctl/pkg/document"
|
"opendev.org/airship/airshipctl/pkg/document"
|
||||||
"opendev.org/airship/airshipctl/pkg/log"
|
"opendev.org/airship/airshipctl/pkg/log"
|
||||||
@ -66,17 +69,26 @@ func TestBootstrapIso(t *testing.T) {
|
|||||||
defer cleanup(t)
|
defer cleanup(t)
|
||||||
|
|
||||||
volBind := tempVol + ":/dst"
|
volBind := tempVol + ":/dst"
|
||||||
testErr := fmt.Errorf("testErr")
|
testErr := fmt.Errorf("TestErr")
|
||||||
testCfg := &config.Bootstrap{
|
testCfg := &api.ImageConfiguration{
|
||||||
Container: &config.Container{
|
Container: &api.Container{
|
||||||
Volume: volBind,
|
Volume: volBind,
|
||||||
ContainerRuntime: "docker",
|
ContainerRuntime: "docker",
|
||||||
},
|
},
|
||||||
Builder: &config.Builder{
|
Builder: &api.Builder{
|
||||||
UserDataFileName: "user-data",
|
UserDataFileName: "user-data",
|
||||||
NetworkConfigFileName: "net-conf",
|
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{
|
expOut := []string{
|
||||||
"Creating cloud-init for ephemeral K8s",
|
"Creating cloud-init for ephemeral K8s",
|
||||||
fmt.Sprintf("Running default container command. Mounted dir: [%s]", volBind),
|
fmt.Sprintf("Running default container command. Mounted dir: [%s]", volBind),
|
||||||
@ -87,7 +99,8 @@ func TestBootstrapIso(t *testing.T) {
|
|||||||
|
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
builder *mockContainer
|
builder *mockContainer
|
||||||
cfg *config.Bootstrap
|
cfg *api.ImageConfiguration
|
||||||
|
doc *MockDocument
|
||||||
debug bool
|
debug bool
|
||||||
expectedOut []string
|
expectedOut []string
|
||||||
expectedErr error
|
expectedErr error
|
||||||
@ -97,16 +110,15 @@ func TestBootstrapIso(t *testing.T) {
|
|||||||
runCommand: func() error { return testErr },
|
runCommand: func() error { return testErr },
|
||||||
},
|
},
|
||||||
cfg: testCfg,
|
cfg: testCfg,
|
||||||
|
doc: testDoc,
|
||||||
debug: false,
|
debug: false,
|
||||||
expectedOut: []string{expOut[0], expOut[1]},
|
expectedOut: []string{expOut[0], expOut[1]},
|
||||||
expectedErr: testErr,
|
expectedErr: testErr,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
builder: &mockContainer{
|
builder: testBuilder,
|
||||||
runCommand: func() error { return nil },
|
|
||||||
getID: func() string { return "TESTID" },
|
|
||||||
},
|
|
||||||
cfg: testCfg,
|
cfg: testCfg,
|
||||||
|
doc: testDoc,
|
||||||
debug: true,
|
debug: true,
|
||||||
expectedOut: []string{expOut[0], expOut[1], expOut[2], expOut[3]},
|
expectedOut: []string{expOut[0], expOut[1], expOut[2], expOut[3]},
|
||||||
expectedErr: nil,
|
expectedErr: nil,
|
||||||
@ -118,16 +130,27 @@ func TestBootstrapIso(t *testing.T) {
|
|||||||
rmContainer: func() error { return testErr },
|
rmContainer: func() error { return testErr },
|
||||||
},
|
},
|
||||||
cfg: testCfg,
|
cfg: testCfg,
|
||||||
|
doc: testDoc,
|
||||||
debug: false,
|
debug: false,
|
||||||
expectedOut: []string{expOut[0], expOut[1], expOut[2], expOut[4]},
|
expectedOut: []string{expOut[0], expOut[1], expOut[2], expOut[4]},
|
||||||
expectedErr: testErr,
|
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 {
|
for _, tt := range tests {
|
||||||
outBuf := &bytes.Buffer{}
|
outBuf := &bytes.Buffer{}
|
||||||
log.Init(tt.debug, outBuf)
|
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()
|
actualOut := outBuf.String()
|
||||||
|
|
||||||
for _, line := range tt.expectedOut {
|
for _, line := range tt.expectedOut {
|
||||||
@ -144,14 +167,14 @@ func TestVerifyInputs(t *testing.T) {
|
|||||||
|
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
name string
|
name string
|
||||||
cfg *config.Bootstrap
|
cfg *api.ImageConfiguration
|
||||||
args []string
|
args []string
|
||||||
expectedErr error
|
expectedErr error
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
name: "missing-container-field",
|
name: "missing-container-field",
|
||||||
cfg: &config.Bootstrap{
|
cfg: &api.ImageConfiguration{
|
||||||
Container: &config.Container{},
|
Container: &api.Container{},
|
||||||
},
|
},
|
||||||
expectedErr: config.ErrMissingConfig{
|
expectedErr: config.ErrMissingConfig{
|
||||||
What: "Must specify volume bind for ISO builder container",
|
What: "Must specify volume bind for ISO builder container",
|
||||||
@ -159,11 +182,11 @@ func TestVerifyInputs(t *testing.T) {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "missing-filenames",
|
name: "missing-filenames",
|
||||||
cfg: &config.Bootstrap{
|
cfg: &api.ImageConfiguration{
|
||||||
Container: &config.Container{
|
Container: &api.Container{
|
||||||
Volume: tempVol + ":/dst",
|
Volume: tempVol + ":/dst",
|
||||||
},
|
},
|
||||||
Builder: &config.Builder{},
|
Builder: &api.Builder{},
|
||||||
},
|
},
|
||||||
expectedErr: config.ErrMissingConfig{
|
expectedErr: config.ErrMissingConfig{
|
||||||
What: "UserDataFileName or NetworkConfigFileName are not specified in ISO builder config",
|
What: "UserDataFileName or NetworkConfigFileName are not specified in ISO builder config",
|
||||||
@ -171,11 +194,11 @@ func TestVerifyInputs(t *testing.T) {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "invalid-host-path",
|
name: "invalid-host-path",
|
||||||
cfg: &config.Bootstrap{
|
cfg: &api.ImageConfiguration{
|
||||||
Container: &config.Container{
|
Container: &api.Container{
|
||||||
Volume: tempVol + ":/dst:/dst1",
|
Volume: tempVol + ":/dst:/dst1",
|
||||||
},
|
},
|
||||||
Builder: &config.Builder{
|
Builder: &api.Builder{
|
||||||
UserDataFileName: "user-data",
|
UserDataFileName: "user-data",
|
||||||
NetworkConfigFileName: "net-conf",
|
NetworkConfigFileName: "net-conf",
|
||||||
},
|
},
|
||||||
@ -186,11 +209,11 @@ func TestVerifyInputs(t *testing.T) {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "success",
|
name: "success",
|
||||||
cfg: &config.Bootstrap{
|
cfg: &api.ImageConfiguration{
|
||||||
Container: &config.Container{
|
Container: &api.Container{
|
||||||
Volume: tempVol,
|
Volume: tempVol,
|
||||||
},
|
},
|
||||||
Builder: &config.Builder{
|
Builder: &api.Builder{
|
||||||
UserDataFileName: "user-data",
|
UserDataFileName: "user-data",
|
||||||
NetworkConfigFileName: "net-conf",
|
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
|
// Management configuration which will be used for all hosts in the cluster
|
||||||
ManagementConfiguration string `json:"managementConfiguration"`
|
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
|
// 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.
|
// Management configuration defines management information for all baremetal hosts in a cluster.
|
||||||
ManagementConfiguration map[string]*ManagementConfiguration `json:"managementConfiguration"`
|
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
|
// loadedConfigPath is the full path to the the location of the config
|
||||||
// file from which this config was loaded
|
// file from which this config was loaded
|
||||||
// +not persisted in file
|
// +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
|
// GetManifests returns all of the Manifests associated with the Config sorted by name
|
||||||
func (c *Config) GetManifests() []*Manifest {
|
func (c *Config) GetManifests() []*Manifest {
|
||||||
keys := make([]string, 0, len(c.Manifests))
|
keys := make([]string, 0, len(c.Manifests))
|
||||||
|
@ -80,30 +80,10 @@ func TestString(t *testing.T) {
|
|||||||
name: "repo-checkout",
|
name: "repo-checkout",
|
||||||
stringer: testutil.DummyRepoCheckout(),
|
stringer: testutil.DummyRepoCheckout(),
|
||||||
},
|
},
|
||||||
{
|
|
||||||
name: "bootstrapinfo",
|
|
||||||
stringer: testutil.DummyBootstrapInfo(),
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
name: "managementconfiguration",
|
name: "managementconfiguration",
|
||||||
stringer: testutil.DummyManagementConfiguration(),
|
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 {
|
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) {
|
func TestCurrentContextManagementConfig(t *testing.T) {
|
||||||
conf, cleanup := testutil.InitConfig(t)
|
conf, cleanup := testutil.InitConfig(t)
|
||||||
defer cleanup(t)
|
defer cleanup(t)
|
||||||
|
@ -43,7 +43,6 @@ const (
|
|||||||
AirshipConfigGroup = "airshipit.org"
|
AirshipConfigGroup = "airshipit.org"
|
||||||
AirshipConfigKind = "Config"
|
AirshipConfigKind = "Config"
|
||||||
AirshipConfigVersion = "v1alpha1"
|
AirshipConfigVersion = "v1alpha1"
|
||||||
AirshipDefaultBootstrapInfo = "default"
|
|
||||||
AirshipDefaultContext = "default"
|
AirshipDefaultContext = "default"
|
||||||
AirshipDefaultDirectoryPermission = 0750
|
AirshipDefaultDirectoryPermission = 0750
|
||||||
AirshipDefaultFilePermission = 0640
|
AirshipDefaultFilePermission = 0640
|
||||||
@ -57,8 +56,6 @@ const (
|
|||||||
AirshipPluginPathEnv = "AIRSHIP_KUSTOMIZE_PLUGINS"
|
AirshipPluginPathEnv = "AIRSHIP_KUSTOMIZE_PLUGINS"
|
||||||
|
|
||||||
// Modules
|
// Modules
|
||||||
AirshipDefaultBootstrapImage = "quay.io/airshipit/isogen:latest-ubuntu_focal"
|
|
||||||
AirshipDefaultIsoURL = "http://localhost:8099/ubuntu-focal.iso"
|
|
||||||
AirshipDefaultManagementType = redfish.ClientType
|
AirshipDefaultManagementType = redfish.ClientType
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -107,16 +107,6 @@ func (e ErrMissingRepoCheckoutOptions) Error() string {
|
|||||||
return "Missing repository checkout options."
|
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
|
// ErrInvalidConfig returned in case of incorrect configuration
|
||||||
type ErrInvalidConfig struct {
|
type ErrInvalidConfig struct {
|
||||||
What string
|
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
|
clusterKubeconf: dummy_cluster_target
|
||||||
managementConfiguration: dummy_management_config
|
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
|
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:
|
clusters:
|
||||||
dummy_cluster:
|
dummy_cluster:
|
||||||
clusterType:
|
clusterType:
|
||||||
ephemeral:
|
ephemeral:
|
||||||
bootstrapInfo: dummy_bootstrap_config
|
|
||||||
clusterKubeconf: dummy_cluster_ephemeral
|
clusterKubeconf: dummy_cluster_ephemeral
|
||||||
managementConfiguration: dummy_management_config
|
managementConfiguration: dummy_management_config
|
||||||
target:
|
target:
|
||||||
bootstrapInfo: dummy_bootstrap_config
|
|
||||||
clusterKubeconf: dummy_cluster_target
|
clusterKubeconf: dummy_cluster_target
|
||||||
managementConfiguration: dummy_management_config
|
managementConfiguration: dummy_management_config
|
||||||
contexts:
|
contexts:
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
Cluster: dummy_cluster
|
Cluster: dummy_cluster
|
||||||
target:
|
target:
|
||||||
bootstrapInfo: dummy_bootstrap_config
|
|
||||||
clusterKubeconf: dummy_cluster_target
|
clusterKubeconf: dummy_cluster_target
|
||||||
managementConfiguration: dummy_management_config
|
managementConfiguration: dummy_management_config
|
||||||
|
|
||||||
|
@ -25,23 +25,6 @@ func NewConfig() *Config {
|
|||||||
return &Config{
|
return &Config{
|
||||||
Kind: AirshipConfigKind,
|
Kind: AirshipConfigKind,
|
||||||
APIVersion: AirshipConfigAPIVersion,
|
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{
|
Permissions: Permissions{
|
||||||
DirectoryPermission: AirshipDefaultDirectoryPermission,
|
DirectoryPermission: AirshipDefaultDirectoryPermission,
|
||||||
@ -84,7 +67,6 @@ func NewContext() *Context {
|
|||||||
func NewCluster() *Cluster {
|
func NewCluster() *Cluster {
|
||||||
return &Cluster{
|
return &Cluster{
|
||||||
NameInKubeconf: "",
|
NameInKubeconf: "",
|
||||||
Bootstrap: AirshipDefaultBootstrapInfo,
|
|
||||||
ManagementConfiguration: AirshipDefaultManagementConfiguration,
|
ManagementConfiguration: AirshipDefaultManagementConfiguration,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -45,14 +45,13 @@ func (e ErrUnknownManagementType) Error() string {
|
|||||||
return fmt.Sprintf("unknown management type: %s", e.Type)
|
return fmt.Sprintf("unknown management type: %s", e.Type)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ErrMissingBootstrapInfoOption is an error that indicates a bootstrap option is missing in the airshipctl
|
// ErrMissingOption is an error that indicates a remote direct config option is missing
|
||||||
// bootstrapInfo configuration.
|
type ErrMissingOption struct {
|
||||||
type ErrMissingBootstrapInfoOption struct {
|
|
||||||
What string
|
What string
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e ErrMissingBootstrapInfoOption) Error() string {
|
func (e ErrMissingOption) Error() string {
|
||||||
return fmt.Sprintf("missing bootstrapInfo option: %s", e.What)
|
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.
|
// ErrNoHostsFound is an error that indicates that no hosts matched the selection criteria passed to a manager.
|
||||||
|
@ -15,7 +15,9 @@
|
|||||||
package remote
|
package remote
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
api "opendev.org/airship/airshipctl/pkg/api/v1alpha1"
|
||||||
"opendev.org/airship/airshipctl/pkg/config"
|
"opendev.org/airship/airshipctl/pkg/config"
|
||||||
|
"opendev.org/airship/airshipctl/pkg/document"
|
||||||
"opendev.org/airship/airshipctl/pkg/environment"
|
"opendev.org/airship/airshipctl/pkg/environment"
|
||||||
"opendev.org/airship/airshipctl/pkg/log"
|
"opendev.org/airship/airshipctl/pkg/log"
|
||||||
|
|
||||||
@ -25,14 +27,30 @@ import (
|
|||||||
// DoRemoteDirect bootstraps the ephemeral node.
|
// DoRemoteDirect bootstraps the ephemeral node.
|
||||||
func (b baremetalHost) DoRemoteDirect(settings *environment.AirshipCTLSettings) error {
|
func (b baremetalHost) DoRemoteDirect(settings *environment.AirshipCTLSettings) error {
|
||||||
cfg := settings.Config
|
cfg := settings.Config
|
||||||
bootstrapSettings, err := cfg.CurrentContextBootstrapInfo()
|
|
||||||
|
root, err := cfg.CurrentContextEntryPoint(config.BootstrapPhase)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
remoteConfig := bootstrapSettings.RemoteDirect
|
docBundle, err := document.NewBundleByPath(root)
|
||||||
if remoteConfig == nil {
|
if err != nil {
|
||||||
return config.ErrMissingConfig{What: "RemoteDirect options not defined in bootstrap config"}
|
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(),
|
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
|
// Perform remote direct operations
|
||||||
if remoteConfig.IsoURL == "" {
|
if remoteDirectConfiguration.IsoURL == "" {
|
||||||
return ErrMissingBootstrapInfoOption{What: "isoURL"}
|
return ErrMissingOption{What: "isoURL"}
|
||||||
}
|
}
|
||||||
|
|
||||||
err = b.SetVirtualMedia(b.Context, remoteConfig.IsoURL)
|
err = b.SetVirtualMedia(b.Context, remoteDirectConfiguration.IsoURL)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -20,8 +20,6 @@ import (
|
|||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
"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/power"
|
||||||
"opendev.org/airship/airshipctl/pkg/remote/redfish"
|
"opendev.org/airship/airshipctl/pkg/remote/redfish"
|
||||||
"opendev.org/airship/airshipctl/testutil/redfishutils"
|
"opendev.org/airship/airshipctl/testutil/redfishutils"
|
||||||
@ -35,18 +33,6 @@ const (
|
|||||||
password = "password"
|
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) {
|
func TestDoRemoteDirectMissingConfigOpts(t *testing.T) {
|
||||||
ctx, rMock, err := redfishutils.NewClient(redfishURL, false, false, username, password)
|
ctx, rMock, err := redfishutils.NewClient(redfishURL, false, false, username, password)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
@ -60,8 +46,12 @@ func TestDoRemoteDirectMissingConfigOpts(t *testing.T) {
|
|||||||
password,
|
password,
|
||||||
}
|
}
|
||||||
|
|
||||||
settings := initSettings(t, withRemoteDirectConfig(nil), withTestDataPath("base"))
|
settings := initSettings(t, withTestDataPath("noremote"))
|
||||||
|
// there must be document.ErrDocNotFound
|
||||||
err = ephemeralHost.DoRemoteDirect(settings)
|
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)
|
assert.Error(t, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -81,10 +71,10 @@ func TestDoRemoteDirectMissingISOURL(t *testing.T) {
|
|||||||
password,
|
password,
|
||||||
}
|
}
|
||||||
|
|
||||||
cfg := &config.RemoteDirect{}
|
settings := initSettings(t, withTestDataPath("noisourl"))
|
||||||
|
|
||||||
settings := initSettings(t, withRemoteDirectConfig(cfg), withTestDataPath("base"))
|
|
||||||
err = ephemeralHost.DoRemoteDirect(settings)
|
err = ephemeralHost.DoRemoteDirect(settings)
|
||||||
|
expectedErrorMessage := `missing option: isoURL`
|
||||||
|
assert.Equal(t, expectedErrorMessage, fmt.Sprintf("%s", err))
|
||||||
assert.Error(t, err)
|
assert.Error(t, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -108,11 +98,7 @@ func TestDoRemoteDirectRedfish(t *testing.T) {
|
|||||||
password,
|
password,
|
||||||
}
|
}
|
||||||
|
|
||||||
cfg := &config.RemoteDirect{
|
settings := initSettings(t, withTestDataPath("base"))
|
||||||
IsoURL: isoURL,
|
|
||||||
}
|
|
||||||
|
|
||||||
settings := initSettings(t, withRemoteDirectConfig(cfg), withTestDataPath("base"))
|
|
||||||
err = ephemeralHost.DoRemoteDirect(settings)
|
err = ephemeralHost.DoRemoteDirect(settings)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
}
|
}
|
||||||
@ -138,11 +124,7 @@ func TestDoRemoteDirectRedfishNodePoweredOff(t *testing.T) {
|
|||||||
password,
|
password,
|
||||||
}
|
}
|
||||||
|
|
||||||
cfg := &config.RemoteDirect{
|
settings := initSettings(t, withTestDataPath("base"))
|
||||||
IsoURL: isoURL,
|
|
||||||
}
|
|
||||||
|
|
||||||
settings := initSettings(t, withRemoteDirectConfig(cfg), withTestDataPath("base"))
|
|
||||||
err = ephemeralHost.DoRemoteDirect(settings)
|
err = ephemeralHost.DoRemoteDirect(settings)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
}
|
}
|
||||||
@ -169,11 +151,7 @@ func TestDoRemoteDirectRedfishVirtualMediaError(t *testing.T) {
|
|||||||
password,
|
password,
|
||||||
}
|
}
|
||||||
|
|
||||||
cfg := &config.RemoteDirect{
|
settings := initSettings(t, withTestDataPath("base"))
|
||||||
IsoURL: isoURL,
|
|
||||||
}
|
|
||||||
|
|
||||||
settings := initSettings(t, withRemoteDirectConfig(cfg), withTestDataPath("base"))
|
|
||||||
|
|
||||||
err = ephemeralHost.DoRemoteDirect(settings)
|
err = ephemeralHost.DoRemoteDirect(settings)
|
||||||
_, ok := err.(redfish.ErrRedfishClient)
|
_, ok := err.(redfish.ErrRedfishClient)
|
||||||
@ -202,11 +180,7 @@ func TestDoRemoteDirectRedfishBootSourceError(t *testing.T) {
|
|||||||
password,
|
password,
|
||||||
}
|
}
|
||||||
|
|
||||||
cfg := &config.RemoteDirect{
|
settings := initSettings(t, withTestDataPath("base"))
|
||||||
IsoURL: isoURL,
|
|
||||||
}
|
|
||||||
|
|
||||||
settings := initSettings(t, withRemoteDirectConfig(cfg), withTestDataPath("base"))
|
|
||||||
|
|
||||||
err = ephemeralHost.DoRemoteDirect(settings)
|
err = ephemeralHost.DoRemoteDirect(settings)
|
||||||
_, ok := err.(redfish.ErrRedfishClient)
|
_, ok := err.(redfish.ErrRedfishClient)
|
||||||
@ -236,11 +210,7 @@ func TestDoRemoteDirectRedfishRebootError(t *testing.T) {
|
|||||||
password,
|
password,
|
||||||
}
|
}
|
||||||
|
|
||||||
cfg := &config.RemoteDirect{
|
settings := initSettings(t, withTestDataPath("base"))
|
||||||
IsoURL: isoURL,
|
|
||||||
}
|
|
||||||
|
|
||||||
settings := initSettings(t, withRemoteDirectConfig(cfg), withTestDataPath("base"))
|
|
||||||
|
|
||||||
err = ephemeralHost.DoRemoteDirect(settings)
|
err = ephemeralHost.DoRemoteDirect(settings)
|
||||||
_, ok := err.(redfish.ErrRedfishClient)
|
_, ok := err.(redfish.ErrRedfishClient)
|
||||||
|
@ -1,2 +1,3 @@
|
|||||||
resources:
|
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,
|
DirectoryPermission: config.AirshipDefaultDirectoryPermission,
|
||||||
FilePermission: config.AirshipDefaultFilePermission,
|
FilePermission: config.AirshipDefaultFilePermission,
|
||||||
},
|
},
|
||||||
BootstrapInfo: map[string]*config.Bootstrap{
|
|
||||||
"dummy_bootstrap_config": DummyBootstrapInfo(),
|
|
||||||
},
|
|
||||||
Contexts: map[string]*config.Context{
|
Contexts: map[string]*config.Context{
|
||||||
"dummy_context": DummyContext(),
|
"dummy_context": DummyContext(),
|
||||||
},
|
},
|
||||||
@ -92,7 +89,6 @@ func DummyCluster() *config.Cluster {
|
|||||||
cluster.CertificateAuthority = "dummy_ca"
|
cluster.CertificateAuthority = "dummy_ca"
|
||||||
c.SetKubeCluster(cluster)
|
c.SetKubeCluster(cluster)
|
||||||
c.NameInKubeconf = "dummy_cluster_target"
|
c.NameInKubeconf = "dummy_cluster_target"
|
||||||
c.Bootstrap = "dummy_bootstrap_config"
|
|
||||||
c.ManagementConfiguration = "dummy_management_config"
|
c.ManagementConfiguration = "dummy_management_config"
|
||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
@ -227,26 +223,6 @@ func DummyAuthInfoOptions() *config.AuthInfoOptions {
|
|||||||
return authinfo
|
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
|
// DummyManagementConfiguration creates a management configuration for unit testing
|
||||||
func DummyManagementConfiguration() *config.ManagementConfiguration {
|
func DummyManagementConfiguration() *config.ManagementConfiguration {
|
||||||
return &config.ManagementConfiguration{
|
return &config.ManagementConfiguration{
|
||||||
@ -283,22 +259,18 @@ clusters:
|
|||||||
def:
|
def:
|
||||||
clusterType:
|
clusterType:
|
||||||
ephemeral:
|
ephemeral:
|
||||||
bootstrapInfo: ""
|
|
||||||
clusterKubeconf: def_ephemeral
|
clusterKubeconf: def_ephemeral
|
||||||
target:
|
target:
|
||||||
bootstrapInfo: ""
|
|
||||||
clusterKubeconf: def_target
|
clusterKubeconf: def_target
|
||||||
onlyinkubeconf:
|
onlyinkubeconf:
|
||||||
clusterType:
|
clusterType:
|
||||||
target:
|
target:
|
||||||
bootstrapInfo: ""
|
|
||||||
clusterKubeconf: onlyinkubeconf_target
|
clusterKubeconf: onlyinkubeconf_target
|
||||||
wrongonlyinconfig:
|
wrongonlyinconfig:
|
||||||
clusterType: {}
|
clusterType: {}
|
||||||
wrongonlyinkubeconf:
|
wrongonlyinkubeconf:
|
||||||
clusterType:
|
clusterType:
|
||||||
target:
|
target:
|
||||||
bootstrapInfo: ""
|
|
||||||
clusterKubeconf: wrongonlyinkubeconf_target
|
clusterKubeconf: wrongonlyinkubeconf_target
|
||||||
clustertypenil:
|
clustertypenil:
|
||||||
clusterType: null
|
clusterType: null
|
||||||
|
@ -54,18 +54,6 @@ function generate_airshipconf {
|
|||||||
|
|
||||||
cat <<EOL > ${AIRSHIPCONFIG}
|
cat <<EOL > ${AIRSHIPCONFIG}
|
||||||
apiVersion: airshipit.org/v1alpha1
|
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:
|
clusters:
|
||||||
${CONTEXT}_${cluster}:
|
${CONTEXT}_${cluster}:
|
||||||
clusterType:
|
clusterType:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user