Merge pull request #9449 from johngmyers/userdata-task

Refactor BootstrapScript into a Task
This commit is contained in:
Kubernetes Prow Robot 2020-06-28 16:40:14 -07:00 committed by GitHub
commit d461bfddaf
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
20 changed files with 251 additions and 146 deletions

View File

@ -75,7 +75,9 @@ go_test(
"//pkg/apis/kops:go_default_library",
"//pkg/apis/nodeup:go_default_library",
"//pkg/testutils/golden:go_default_library",
"//upup/pkg/fi:go_default_library",
"//util/pkg/architectures:go_default_library",
"//vendor/github.com/stretchr/testify/require:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
],
)

View File

@ -33,9 +33,9 @@ const DefaultInstanceType = "ecs.n2.medium"
type ScalingGroupModelBuilder struct {
*ALIModelContext
BootstrapScript *model.BootstrapScript
Lifecycle *fi.Lifecycle
SecurityLifecycle *fi.Lifecycle
BootstrapScriptBuilder *model.BootstrapScriptBuilder
Lifecycle *fi.Lifecycle
SecurityLifecycle *fi.Lifecycle
}
var _ fi.ModelBuilder = &ScalingGroupModelBuilder{}
@ -129,7 +129,7 @@ func (b *ScalingGroupModelBuilder) Build(c *fi.ModelBuilderContext) error {
return err
}
launchConfiguration.SSHKey = b.LinkToSSHKey()
if launchConfiguration.UserData, err = b.BootstrapScript.ResourceNodeUp(ig, b.Cluster); err != nil {
if launchConfiguration.UserData, err = b.BootstrapScriptBuilder.ResourceNodeUp(c, ig); err != nil {
return err
}
}

View File

@ -45,9 +45,9 @@ const (
type AutoscalingGroupModelBuilder struct {
*AWSModelContext
BootstrapScript *model.BootstrapScript
Lifecycle *fi.Lifecycle
SecurityLifecycle *fi.Lifecycle
BootstrapScriptBuilder *model.BootstrapScriptBuilder
Lifecycle *fi.Lifecycle
SecurityLifecycle *fi.Lifecycle
}
var _ fi.ModelBuilder = &AutoscalingGroupModelBuilder{}
@ -261,7 +261,7 @@ func (b *AutoscalingGroupModelBuilder) buildLaunchConfigurationTask(c *fi.ModelB
}
// @step: add the instancegroup userdata
if t.UserData, err = b.BootstrapScript.ResourceNodeUp(ig, b.Cluster); err != nil {
if t.UserData, err = b.BootstrapScriptBuilder.ResourceNodeUp(c, ig); err != nil {
return nil, err
}

View File

@ -43,16 +43,26 @@ type NodeUpConfigBuilder interface {
BuildConfig(ig *kops.InstanceGroup) (*nodeup.Config, error)
}
// BootstrapScript creates the bootstrap script
type BootstrapScript struct {
// BootstrapScriptBuilder creates the bootstrap script
type BootstrapScriptBuilder struct {
NodeUpSource map[architectures.Architecture]string
NodeUpSourceHash map[architectures.Architecture]string
NodeUpConfigBuilder NodeUpConfigBuilder
}
type BootstrapScript struct {
Name string
ig *kops.InstanceGroup
builder *BootstrapScriptBuilder
resource fi.TaskDependentResource
}
var _ fi.Task = &BootstrapScript{}
var _ fi.HasName = &BootstrapScript{}
// kubeEnv returns the nodeup config for the instance group
func (b *BootstrapScript) kubeEnv(ig *kops.InstanceGroup) (string, error) {
config, err := b.NodeUpConfigBuilder.BuildConfig(ig)
config, err := b.builder.NodeUpConfigBuilder.BuildConfig(ig)
if err != nil {
return "", err
}
@ -135,7 +145,7 @@ func (b *BootstrapScript) buildEnvironmentVariables(cluster *kops.Cluster) (map[
// ResourceNodeUp generates and returns a nodeup (bootstrap) script from a
// template file, substituting in specific env vars & cluster spec configuration
func (b *BootstrapScript) ResourceNodeUp(ig *kops.InstanceGroup, cluster *kops.Cluster) (*fi.ResourceHolder, error) {
func (b *BootstrapScriptBuilder) ResourceNodeUp(c *fi.ModelBuilderContext, ig *kops.InstanceGroup) (*fi.ResourceHolder, error) {
// Bastions can have AdditionalUserData, but if there isn't any skip this part
if ig.IsBastion() && len(ig.Spec.AdditionalUserData) == 0 {
templateResource, err := NewTemplateResource("nodeup", "", nil, nil)
@ -145,25 +155,40 @@ func (b *BootstrapScript) ResourceNodeUp(ig *kops.InstanceGroup, cluster *kops.C
return fi.WrapResource(templateResource), nil
}
task := &BootstrapScript{
Name: ig.Name,
ig: ig,
builder: b,
}
task.resource.Task = task
c.AddTask(task)
return fi.WrapResource(&task.resource), nil
}
func (b *BootstrapScript) GetName() *string {
return &b.Name
}
func (b *BootstrapScript) Run(c *fi.Context) error {
functions := template.FuncMap{
"NodeUpSourceAmd64": func() string {
return b.NodeUpSource[architectures.ArchitectureAmd64]
return b.builder.NodeUpSource[architectures.ArchitectureAmd64]
},
"NodeUpSourceHashAmd64": func() string {
return b.NodeUpSourceHash[architectures.ArchitectureAmd64]
return b.builder.NodeUpSourceHash[architectures.ArchitectureAmd64]
},
"NodeUpSourceArm64": func() string {
return b.NodeUpSource[architectures.ArchitectureArm64]
return b.builder.NodeUpSource[architectures.ArchitectureArm64]
},
"NodeUpSourceHashArm64": func() string {
return b.NodeUpSourceHash[architectures.ArchitectureArm64]
return b.builder.NodeUpSourceHash[architectures.ArchitectureArm64]
},
"KubeEnv": func() (string, error) {
return b.kubeEnv(ig)
return b.kubeEnv(b.ig)
},
"EnvironmentVariables": func() (string, error) {
env, err := b.buildEnvironmentVariables(cluster)
env, err := b.buildEnvironmentVariables(c.Cluster)
if err != nil {
return "", err
}
@ -183,11 +208,11 @@ func (b *BootstrapScript) ResourceNodeUp(ig *kops.InstanceGroup, cluster *kops.C
},
"ProxyEnv": func() string {
return b.createProxyEnv(cluster.Spec.EgressProxy)
return b.createProxyEnv(c.Cluster.Spec.EgressProxy)
},
"ClusterSpec": func() (string, error) {
cs := cluster.Spec
cs := c.Cluster.Spec
spec := make(map[string]interface{})
spec["cloudConfig"] = cs.CloudConfig
@ -206,7 +231,7 @@ func (b *BootstrapScript) ResourceNodeUp(ig *kops.InstanceGroup, cluster *kops.C
}
}
if ig.IsMaster() {
if b.ig.IsMaster() {
spec["encryptionConfig"] = cs.EncryptionConfig
spec["etcdClusters"] = make(map[string]kops.EtcdClusterSpec)
spec["kubeAPIServer"] = cs.KubeAPIServer
@ -231,7 +256,7 @@ func (b *BootstrapScript) ResourceNodeUp(ig *kops.InstanceGroup, cluster *kops.C
}
}
hooks, err := b.getRelevantHooks(cs.Hooks, ig.Spec.Role)
hooks, err := b.getRelevantHooks(cs.Hooks, b.ig.Spec.Role)
if err != nil {
return "", err
}
@ -239,7 +264,7 @@ func (b *BootstrapScript) ResourceNodeUp(ig *kops.InstanceGroup, cluster *kops.C
spec["hooks"] = hooks
}
fileAssets, err := b.getRelevantFileAssets(cs.FileAssets, ig.Spec.Role)
fileAssets, err := b.getRelevantFileAssets(cs.FileAssets, b.ig.Spec.Role)
if err != nil {
return "", err
}
@ -256,11 +281,11 @@ func (b *BootstrapScript) ResourceNodeUp(ig *kops.InstanceGroup, cluster *kops.C
"IGSpec": func() (string, error) {
spec := make(map[string]interface{})
spec["kubelet"] = ig.Spec.Kubelet
spec["nodeLabels"] = ig.Spec.NodeLabels
spec["taints"] = ig.Spec.Taints
spec["kubelet"] = b.ig.Spec.Kubelet
spec["nodeLabels"] = b.ig.Spec.NodeLabels
spec["taints"] = b.ig.Spec.Taints
hooks, err := b.getRelevantHooks(ig.Spec.Hooks, ig.Spec.Role)
hooks, err := b.getRelevantHooks(b.ig.Spec.Hooks, b.ig.Spec.Role)
if err != nil {
return "", err
}
@ -268,7 +293,7 @@ func (b *BootstrapScript) ResourceNodeUp(ig *kops.InstanceGroup, cluster *kops.C
spec["hooks"] = hooks
}
fileAssets, err := b.getRelevantFileAssets(ig.Spec.FileAssets, ig.Spec.Role)
fileAssets, err := b.getRelevantFileAssets(b.ig.Spec.FileAssets, b.ig.Spec.Role)
if err != nil {
return "", err
}
@ -284,17 +309,18 @@ func (b *BootstrapScript) ResourceNodeUp(ig *kops.InstanceGroup, cluster *kops.C
},
}
awsNodeUpTemplate, err := resources.AWSNodeUpTemplate(ig)
awsNodeUpTemplate, err := resources.AWSNodeUpTemplate(b.ig)
if err != nil {
return nil, err
return err
}
templateResource, err := NewTemplateResource("nodeup", awsNodeUpTemplate, functions, nil)
if err != nil {
return nil, err
return err
}
return fi.WrapResource(templateResource), nil
b.resource.Resource = templateResource
return nil
}
// getRelevantHooks returns a list of hooks to be applied to the instance group,

View File

@ -20,9 +20,12 @@ import (
"strings"
"testing"
"github.com/stretchr/testify/require"
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/kops/pkg/apis/kops"
"k8s.io/kops/pkg/apis/nodeup"
"k8s.io/kops/pkg/testutils/golden"
"k8s.io/kops/upup/pkg/fi"
"k8s.io/kops/util/pkg/architectures"
)
@ -121,8 +124,11 @@ func TestBootstrapUserData(t *testing.T) {
for i, x := range cs {
cluster := makeTestCluster(x.HookSpecRoles, x.FileAssetSpecRoles)
group := makeTestInstanceGroup(x.Role, x.HookSpecRoles, x.FileAssetSpecRoles)
c := &fi.ModelBuilderContext{
Tasks: make(map[string]fi.Task),
}
bs := &BootstrapScript{
bs := &BootstrapScriptBuilder{
NodeUpConfigBuilder: &nodeupConfigBuilder{cluster: cluster},
NodeUpSource: map[architectures.Architecture]string{
architectures.ArchitectureAmd64: "NUSourceAmd64",
@ -134,18 +140,16 @@ func TestBootstrapUserData(t *testing.T) {
},
}
// Purposely running this twice to cover issue #3516
_, err := bs.ResourceNodeUp(group, cluster)
if err != nil {
t.Errorf("case %d failed to create nodeup resource. error: %s", i, err)
continue
}
res, err := bs.ResourceNodeUp(group, cluster)
res, err := bs.ResourceNodeUp(c, group)
if err != nil {
t.Errorf("case %d failed to create nodeup resource. error: %s", i, err)
continue
}
require.Contains(t, c.Tasks, "BootstrapScript/testIG")
err = c.Tasks["BootstrapScript/testIG"].Run(&fi.Context{Cluster: cluster})
require.NoError(t, err, "running task")
actual, err := res.AsString()
if err != nil {
t.Errorf("case %d failed to render nodeup resource. error: %s", i, err)
@ -256,6 +260,9 @@ func makeTestCluster(hookSpecRoles []kops.InstanceGroupRole, fileAssetSpecRoles
func makeTestInstanceGroup(role kops.InstanceGroupRole, hookSpecRoles []kops.InstanceGroupRole, fileAssetSpecRoles []kops.InstanceGroupRole) *kops.InstanceGroup {
return &kops.InstanceGroup{
ObjectMeta: v1.ObjectMeta{
Name: "testIG",
},
Spec: kops.InstanceGroupSpec{
Kubelet: &kops.KubeletConfigSpec{
KubeconfigPath: "/etc/kubernetes/igconfig.txt",

View File

@ -30,8 +30,8 @@ import (
type DropletBuilder struct {
*DOModelContext
BootstrapScript *model.BootstrapScript
Lifecycle *fi.Lifecycle
BootstrapScriptBuilder *model.BootstrapScriptBuilder
Lifecycle *fi.Lifecycle
}
var _ fi.ModelBuilder = &DropletBuilder{}
@ -78,7 +78,7 @@ func (d *DropletBuilder) Build(c *fi.ModelBuilderContext) error {
droplet.Tags = append(droplet.Tags, do.TagKubernetesClusterInstanceGroupPrefix+":"+"nodes")
}
userData, err := d.BootstrapScript.ResourceNodeUp(ig, d.Cluster)
userData, err := d.BootstrapScriptBuilder.ResourceNodeUp(c, ig)
if err != nil {
return err
}

View File

@ -40,8 +40,8 @@ const (
type AutoscalingGroupModelBuilder struct {
*GCEModelContext
BootstrapScript *model.BootstrapScript
Lifecycle *fi.Lifecycle
BootstrapScriptBuilder *model.BootstrapScriptBuilder
Lifecycle *fi.Lifecycle
}
var _ fi.ModelBuilder = &AutoscalingGroupModelBuilder{}
@ -50,7 +50,7 @@ func (b *AutoscalingGroupModelBuilder) Build(c *fi.ModelBuilderContext) error {
for _, ig := range b.InstanceGroups {
name := b.SafeObjectName(ig.ObjectMeta.Name)
startupScript, err := b.BootstrapScript.ResourceNodeUp(ig, b.Cluster)
startupScript, err := b.BootstrapScriptBuilder.ResourceNodeUp(c, ig)
if err != nil {
return err
}

View File

@ -33,8 +33,8 @@ import (
// ServerGroupModelBuilder configures server group objects
type ServerGroupModelBuilder struct {
*OpenstackModelContext
BootstrapScript *model.BootstrapScript
Lifecycle *fi.Lifecycle
BootstrapScriptBuilder *model.BootstrapScriptBuilder
Lifecycle *fi.Lifecycle
}
var _ fi.ModelBuilder = &ServerGroupModelBuilder{}
@ -50,7 +50,6 @@ func (b *ServerGroupModelBuilder) buildInstances(c *fi.ModelBuilderContext, sg *
clusterTag := "KubernetesCluster:" + strings.Replace(b.ClusterName(), ".", "-", -1)
var igUserData *string
igMeta := make(map[string]string)
if ig.Spec.Role != kops.InstanceGroupRoleBastion {
@ -77,18 +76,10 @@ func (b *ServerGroupModelBuilder) buildInstances(c *fi.ModelBuilderContext, sg *
igMeta[openstack.BOOT_VOLUME_SIZE] = v
}
startupScript, err := b.BootstrapScript.ResourceNodeUp(ig, b.Cluster)
startupScript, err := b.BootstrapScriptBuilder.ResourceNodeUp(c, ig)
if err != nil {
return fmt.Errorf("could not create startup script for instance group %s: %v", ig.Name, err)
}
if startupScript != nil {
// var userData bytes.Buffer
startupStr, err := startupScript.AsString()
if err != nil {
return fmt.Errorf("could not create startup script for instance group %s: %v", ig.Name, err)
}
igUserData = fi.String(startupStr)
}
var securityGroups []*openstacktasks.SecurityGroup
securityGroupName := b.SecurityGroupName(ig.Spec.Role)
@ -149,13 +140,11 @@ func (b *ServerGroupModelBuilder) buildInstances(c *fi.ModelBuilderContext, sg *
Tags: []string{clusterTag},
Role: fi.String(string(ig.Spec.Role)),
Port: portTask,
UserData: startupScript,
Metadata: igMeta,
SecurityGroups: ig.Spec.AdditionalSecurityGroups,
AvailabilityZone: az,
}
if igUserData != nil {
instanceTask.UserData = igUserData
}
c.AddTask(instanceTask)
// Associate a floating IP to the master and bastion always if we have external network in router

View File

@ -126,7 +126,7 @@ func Test_ServerGroupModelBuilder(t *testing.T) {
Tags: []string{"KubernetesCluster:cluster"},
Role: s("Master"),
Port: masterPort,
UserData: s(mustUserdataForClusterInstance(cluster, instanceGroups[0])),
UserData: mustUserdataForClusterInstance(cluster, instanceGroups[0]),
Metadata: map[string]string{
"KubernetesCluster": "cluster",
"k8s": "cluster",
@ -172,7 +172,7 @@ func Test_ServerGroupModelBuilder(t *testing.T) {
Tags: []string{"KubernetesCluster:cluster"},
Role: s("Node"),
Port: nodePort,
UserData: s(mustUserdataForClusterInstance(cluster, instanceGroups[1])),
UserData: mustUserdataForClusterInstance(cluster, instanceGroups[1]),
Metadata: map[string]string{
"KubernetesCluster": "cluster",
"k8s": "cluster",
@ -311,7 +311,7 @@ func Test_ServerGroupModelBuilder(t *testing.T) {
Tags: []string{"KubernetesCluster:cluster"},
Role: s("Master"),
Port: masterPort,
UserData: s(mustUserdataForClusterInstance(cluster, instanceGroups[0])),
UserData: mustUserdataForClusterInstance(cluster, instanceGroups[0]),
Metadata: map[string]string{
"KubernetesCluster": "cluster",
"k8s": "cluster",
@ -357,7 +357,7 @@ func Test_ServerGroupModelBuilder(t *testing.T) {
Tags: []string{"KubernetesCluster:cluster"},
Role: s("Node"),
Port: nodePort,
UserData: s(mustUserdataForClusterInstance(cluster, instanceGroups[1])),
UserData: mustUserdataForClusterInstance(cluster, instanceGroups[1]),
Metadata: map[string]string{
"KubernetesCluster": "cluster",
"k8s": "cluster",
@ -398,7 +398,7 @@ func Test_ServerGroupModelBuilder(t *testing.T) {
Tags: []string{"KubernetesCluster:cluster"},
Role: s("Bastion"),
Port: bastionPort,
UserData: s(mustUserdataForClusterInstance(cluster, instanceGroups[2])),
UserData: mustUserdataForClusterInstance(cluster, instanceGroups[2]),
Metadata: map[string]string{
"k8s": "cluster",
"KopsInstanceGroup": "bastion",
@ -578,7 +578,7 @@ func Test_ServerGroupModelBuilder(t *testing.T) {
Tags: []string{"KubernetesCluster:cluster"},
Role: s("Master"),
Port: masterAPort,
UserData: s(mustUserdataForClusterInstance(cluster, instanceGroups[0])),
UserData: mustUserdataForClusterInstance(cluster, instanceGroups[0]),
Metadata: map[string]string{
"KubernetesCluster": "cluster",
"k8s": "cluster",
@ -625,7 +625,7 @@ func Test_ServerGroupModelBuilder(t *testing.T) {
Tags: []string{"KubernetesCluster:cluster"},
Role: s("Master"),
Port: masterBPort,
UserData: s(mustUserdataForClusterInstance(cluster, instanceGroups[0])),
UserData: mustUserdataForClusterInstance(cluster, instanceGroups[0]),
Metadata: map[string]string{
"KubernetesCluster": "cluster",
"k8s": "cluster",
@ -672,7 +672,7 @@ func Test_ServerGroupModelBuilder(t *testing.T) {
Tags: []string{"KubernetesCluster:cluster"},
Role: s("Master"),
Port: masterCPort,
UserData: s(mustUserdataForClusterInstance(cluster, instanceGroups[0])),
UserData: mustUserdataForClusterInstance(cluster, instanceGroups[0]),
Metadata: map[string]string{
"KubernetesCluster": "cluster",
"k8s": "cluster",
@ -718,7 +718,7 @@ func Test_ServerGroupModelBuilder(t *testing.T) {
Tags: []string{"KubernetesCluster:cluster"},
Role: s("Node"),
Port: nodeAPort,
UserData: s(mustUserdataForClusterInstance(cluster, instanceGroups[1])),
UserData: mustUserdataForClusterInstance(cluster, instanceGroups[1]),
Metadata: map[string]string{
"KubernetesCluster": "cluster",
"k8s": "cluster",
@ -764,7 +764,7 @@ func Test_ServerGroupModelBuilder(t *testing.T) {
Tags: []string{"KubernetesCluster:cluster"},
Role: s("Node"),
Port: nodeBPort,
UserData: s(mustUserdataForClusterInstance(cluster, instanceGroups[1])),
UserData: mustUserdataForClusterInstance(cluster, instanceGroups[1]),
Metadata: map[string]string{
"KubernetesCluster": "cluster",
"k8s": "cluster",
@ -810,7 +810,7 @@ func Test_ServerGroupModelBuilder(t *testing.T) {
Tags: []string{"KubernetesCluster:cluster"},
Role: s("Node"),
Port: nodeCPort,
UserData: s(mustUserdataForClusterInstance(cluster, instanceGroups[1])),
UserData: mustUserdataForClusterInstance(cluster, instanceGroups[1]),
Metadata: map[string]string{
"KubernetesCluster": "cluster",
"k8s": "cluster",
@ -1007,7 +1007,7 @@ func Test_ServerGroupModelBuilder(t *testing.T) {
Tags: []string{"KubernetesCluster:cluster"},
Role: s("Master"),
Port: masterAPort,
UserData: s(mustUserdataForClusterInstance(cluster, instanceGroups[0])),
UserData: mustUserdataForClusterInstance(cluster, instanceGroups[0]),
Metadata: map[string]string{
"KubernetesCluster": "cluster",
"k8s": "cluster",
@ -1048,7 +1048,7 @@ func Test_ServerGroupModelBuilder(t *testing.T) {
Tags: []string{"KubernetesCluster:cluster"},
Role: s("Master"),
Port: masterBPort,
UserData: s(mustUserdataForClusterInstance(cluster, instanceGroups[0])),
UserData: mustUserdataForClusterInstance(cluster, instanceGroups[0]),
Metadata: map[string]string{
"KubernetesCluster": "cluster",
"k8s": "cluster",
@ -1089,7 +1089,7 @@ func Test_ServerGroupModelBuilder(t *testing.T) {
Tags: []string{"KubernetesCluster:cluster"},
Role: s("Master"),
Port: masterCPort,
UserData: s(mustUserdataForClusterInstance(cluster, instanceGroups[0])),
UserData: mustUserdataForClusterInstance(cluster, instanceGroups[0]),
Metadata: map[string]string{
"KubernetesCluster": "cluster",
"k8s": "cluster",
@ -1130,7 +1130,7 @@ func Test_ServerGroupModelBuilder(t *testing.T) {
Tags: []string{"KubernetesCluster:cluster"},
Role: s("Node"),
Port: nodeAPort,
UserData: s(mustUserdataForClusterInstance(cluster, instanceGroups[1])),
UserData: mustUserdataForClusterInstance(cluster, instanceGroups[1]),
Metadata: map[string]string{
"KubernetesCluster": "cluster",
"k8s": "cluster",
@ -1176,7 +1176,7 @@ func Test_ServerGroupModelBuilder(t *testing.T) {
Tags: []string{"KubernetesCluster:cluster"},
Role: s("Node"),
Port: nodeBPort,
UserData: s(mustUserdataForClusterInstance(cluster, instanceGroups[1])),
UserData: mustUserdataForClusterInstance(cluster, instanceGroups[1]),
Metadata: map[string]string{
"KubernetesCluster": "cluster",
"k8s": "cluster",
@ -1222,7 +1222,7 @@ func Test_ServerGroupModelBuilder(t *testing.T) {
Tags: []string{"KubernetesCluster:cluster"},
Role: s("Node"),
Port: nodeCPort,
UserData: s(mustUserdataForClusterInstance(cluster, instanceGroups[1])),
UserData: mustUserdataForClusterInstance(cluster, instanceGroups[1]),
Metadata: map[string]string{
"KubernetesCluster": "cluster",
"k8s": "cluster",
@ -1463,7 +1463,7 @@ func Test_ServerGroupModelBuilder(t *testing.T) {
Tags: []string{"KubernetesCluster:cluster"},
Role: s("Master"),
Port: masterAPort,
UserData: s(mustUserdataForClusterInstance(cluster, instanceGroups[0])),
UserData: mustUserdataForClusterInstance(cluster, instanceGroups[0]),
Metadata: map[string]string{
"KubernetesCluster": "cluster",
"k8s": "cluster",
@ -1505,7 +1505,7 @@ func Test_ServerGroupModelBuilder(t *testing.T) {
Tags: []string{"KubernetesCluster:cluster"},
Role: s("Master"),
Port: masterBPort,
UserData: s(mustUserdataForClusterInstance(cluster, instanceGroups[0])),
UserData: mustUserdataForClusterInstance(cluster, instanceGroups[0]),
Metadata: map[string]string{
"KubernetesCluster": "cluster",
"k8s": "cluster",
@ -1547,7 +1547,7 @@ func Test_ServerGroupModelBuilder(t *testing.T) {
Tags: []string{"KubernetesCluster:cluster"},
Role: s("Master"),
Port: masterCPort,
UserData: s(mustUserdataForClusterInstance(cluster, instanceGroups[0])),
UserData: mustUserdataForClusterInstance(cluster, instanceGroups[0]),
Metadata: map[string]string{
"KubernetesCluster": "cluster",
"k8s": "cluster",
@ -1588,7 +1588,7 @@ func Test_ServerGroupModelBuilder(t *testing.T) {
Tags: []string{"KubernetesCluster:cluster"},
Role: s("Node"),
Port: nodeAPort,
UserData: s(mustUserdataForClusterInstance(cluster, instanceGroups[1])),
UserData: mustUserdataForClusterInstance(cluster, instanceGroups[1]),
Metadata: map[string]string{
"KubernetesCluster": "cluster",
"k8s": "cluster",
@ -1629,7 +1629,7 @@ func Test_ServerGroupModelBuilder(t *testing.T) {
Tags: []string{"KubernetesCluster:cluster"},
Role: s("Node"),
Port: nodeBPort,
UserData: s(mustUserdataForClusterInstance(cluster, instanceGroups[1])),
UserData: mustUserdataForClusterInstance(cluster, instanceGroups[1]),
Metadata: map[string]string{
"KubernetesCluster": "cluster",
"k8s": "cluster",
@ -1670,7 +1670,7 @@ func Test_ServerGroupModelBuilder(t *testing.T) {
Tags: []string{"KubernetesCluster:cluster"},
Role: s("Node"),
Port: nodeCPort,
UserData: s(mustUserdataForClusterInstance(cluster, instanceGroups[1])),
UserData: mustUserdataForClusterInstance(cluster, instanceGroups[1]),
Metadata: map[string]string{
"KubernetesCluster": "cluster",
"k8s": "cluster",
@ -1813,7 +1813,7 @@ func Test_ServerGroupModelBuilder(t *testing.T) {
Tags: []string{"KubernetesCluster:cluster"},
Role: s("Master"),
Port: masterAPort,
UserData: s(mustUserdataForClusterInstance(cluster, instanceGroups[0])),
UserData: mustUserdataForClusterInstance(cluster, instanceGroups[0]),
Metadata: map[string]string{
"KubernetesCluster": "cluster",
"k8s": "cluster",
@ -1852,7 +1852,7 @@ func Test_ServerGroupModelBuilder(t *testing.T) {
Tags: []string{"KubernetesCluster:cluster"},
Role: s("Master"),
Port: masterBPort,
UserData: s(mustUserdataForClusterInstance(cluster, instanceGroups[0])),
UserData: mustUserdataForClusterInstance(cluster, instanceGroups[0]),
Metadata: map[string]string{
"KubernetesCluster": "cluster",
"k8s": "cluster",
@ -1891,7 +1891,7 @@ func Test_ServerGroupModelBuilder(t *testing.T) {
Tags: []string{"KubernetesCluster:cluster"},
Role: s("Master"),
Port: masterCPort,
UserData: s(mustUserdataForClusterInstance(cluster, instanceGroups[0])),
UserData: mustUserdataForClusterInstance(cluster, instanceGroups[0]),
Metadata: map[string]string{
"KubernetesCluster": "cluster",
"k8s": "cluster",
@ -1937,7 +1937,7 @@ func Test_ServerGroupModelBuilder(t *testing.T) {
Tags: []string{"KubernetesCluster:cluster"},
Role: s("Node"),
Port: nodeAPort,
UserData: s(mustUserdataForClusterInstance(cluster, instanceGroups[1])),
UserData: mustUserdataForClusterInstance(cluster, instanceGroups[1]),
Metadata: map[string]string{
"KubernetesCluster": "cluster",
"k8s": "cluster",
@ -1975,7 +1975,7 @@ func Test_ServerGroupModelBuilder(t *testing.T) {
Tags: []string{"KubernetesCluster:cluster"},
Role: s("Node"),
Port: nodeBPort,
UserData: s(mustUserdataForClusterInstance(cluster, instanceGroups[1])),
UserData: mustUserdataForClusterInstance(cluster, instanceGroups[1]),
Metadata: map[string]string{
"KubernetesCluster": "cluster",
"k8s": "cluster",
@ -2013,7 +2013,7 @@ func Test_ServerGroupModelBuilder(t *testing.T) {
Tags: []string{"KubernetesCluster:cluster"},
Role: s("Node"),
Port: nodeCPort,
UserData: s(mustUserdataForClusterInstance(cluster, instanceGroups[1])),
UserData: mustUserdataForClusterInstance(cluster, instanceGroups[1]),
Metadata: map[string]string{
"KubernetesCluster": "cluster",
"k8s": "cluster",
@ -2141,7 +2141,7 @@ func Test_ServerGroupModelBuilder(t *testing.T) {
Tags: []string{"KubernetesCluster:cluster"},
Role: s("Master"),
Port: masterPort,
UserData: s(mustUserdataForClusterInstance(cluster, instanceGroups[0])),
UserData: mustUserdataForClusterInstance(cluster, instanceGroups[0]),
Metadata: map[string]string{
"KubernetesCluster": "cluster",
"k8s": "cluster",
@ -2182,7 +2182,7 @@ func Test_ServerGroupModelBuilder(t *testing.T) {
Tags: []string{"KubernetesCluster:cluster"},
Role: s("Node"),
Port: nodePort,
UserData: s(mustUserdataForClusterInstance(cluster, instanceGroups[1])),
UserData: mustUserdataForClusterInstance(cluster, instanceGroups[1]),
Metadata: map[string]string{
"KubernetesCluster": "cluster",
"k8s": "cluster",
@ -2317,7 +2317,7 @@ func Test_ServerGroupModelBuilder(t *testing.T) {
Tags: []string{"KubernetesCluster:cluster"},
Role: s("Master"),
Port: masterPort,
UserData: s(mustUserdataForClusterInstance(cluster, instanceGroups[0])),
UserData: mustUserdataForClusterInstance(cluster, instanceGroups[0]),
Metadata: map[string]string{
"KubernetesCluster": "cluster",
"k8s": "cluster",
@ -2358,7 +2358,7 @@ func Test_ServerGroupModelBuilder(t *testing.T) {
Tags: []string{"KubernetesCluster:cluster"},
Role: s("Node"),
Port: nodePort,
UserData: s(mustUserdataForClusterInstance(cluster, instanceGroups[1])),
UserData: mustUserdataForClusterInstance(cluster, instanceGroups[1]),
Metadata: map[string]string{
"KubernetesCluster": "cluster",
"k8s": "cluster",
@ -2399,7 +2399,7 @@ func Test_ServerGroupModelBuilder(t *testing.T) {
Tags: []string{"KubernetesCluster:cluster"},
Role: s("Bastion"),
Port: bastionPort,
UserData: s(mustUserdataForClusterInstance(cluster, instanceGroups[2])),
UserData: mustUserdataForClusterInstance(cluster, instanceGroups[2]),
Metadata: map[string]string{
"k8s": "cluster",
"KopsInstanceGroup": "bastion",
@ -2495,7 +2495,7 @@ func Test_ServerGroupModelBuilder(t *testing.T) {
Tags: []string{"KubernetesCluster:cluster"},
Role: s("Node"),
Port: nodePort,
UserData: s(mustUserdataForClusterInstance(cluster, instanceGroups[0])),
UserData: mustUserdataForClusterInstance(cluster, instanceGroups[0]),
Metadata: map[string]string{
"KubernetesCluster": "cluster",
"k8s": "cluster",
@ -2591,7 +2591,7 @@ func Test_ServerGroupModelBuilder(t *testing.T) {
Tags: []string{"KubernetesCluster:cluster"},
Role: s("Node"),
Port: nodePort,
UserData: s(mustUserdataForClusterInstance(cluster, instanceGroups[0])),
UserData: mustUserdataForClusterInstance(cluster, instanceGroups[0]),
Metadata: map[string]string{
"KubernetesCluster": "cluster",
"k8s": "cluster",
@ -2685,7 +2685,7 @@ func Test_ServerGroupModelBuilder(t *testing.T) {
Tags: []string{"KubernetesCluster:cluster"},
Role: s("Node"),
Port: nodePort,
UserData: s(mustUserdataForClusterInstance(cluster, instanceGroups[0])),
UserData: mustUserdataForClusterInstance(cluster, instanceGroups[0]),
Metadata: map[string]string{
"KubernetesCluster": "cluster",
"k8s": "cluster",
@ -2712,7 +2712,7 @@ func Test_ServerGroupModelBuilder(t *testing.T) {
for _, testCase := range tests {
t.Run(testCase.desc, func(t *testing.T) {
clusterLifecycle := fi.LifecycleSync
bootstrapScriptBuilder := &model.BootstrapScript{
bootstrapScriptBuilder := &model.BootstrapScriptBuilder{
NodeUpConfigBuilder: &nodeupConfigBuilder{},
NodeUpSource: map[architectures.Architecture]string{
architectures.ArchitectureAmd64: "source-amd64",
@ -2736,11 +2736,23 @@ func Test_ServerGroupModelBuilder(t *testing.T) {
compareErrors(t, err, testCase.expectedError)
expectedTasks := testCase.expectedTasksBuilder(testCase.cluster, testCase.instanceGroups)
for _, ig := range testCase.instanceGroups {
expectedTasks["BootstrapScript/"+ig.Name] = &model.BootstrapScript{Name: ig.Name}
}
if len(expectedTasks) != len(context.Tasks) {
t.Errorf("expected %d tasks, got %d tasks", len(expectedTasks), len(context.Tasks))
}
for taskName, task := range context.Tasks {
if strings.HasPrefix(taskName, "BootstrapScript/") {
err = task.Run(&fi.Context{Cluster: testCase.cluster})
if err != nil {
t.Errorf("failed to run BootstrapScript task: %v", err)
}
}
}
for taskName, task := range expectedTasks {
actual, ok := context.Tasks[taskName]
if !ok {
@ -2784,6 +2796,8 @@ func Test_ServerGroupModelBuilder(t *testing.T) {
t.Run("creates a task for "+taskName, func(t *testing.T) {
compareSecurityGroups(t, actual, expected)
})
case *model.BootstrapScript:
// ignore
default:
t.Errorf("found a task with name %q and type %T", taskName, expected)
}
@ -2798,7 +2812,7 @@ func Test_ServerGroupModelBuilder(t *testing.T) {
}
}
func createBuilderForCluster(cluster *kops.Cluster, instanceGroups []*kops.InstanceGroup, clusterLifecycle fi.Lifecycle, bootstrapScript *model.BootstrapScript) *ServerGroupModelBuilder {
func createBuilderForCluster(cluster *kops.Cluster, instanceGroups []*kops.InstanceGroup, clusterLifecycle fi.Lifecycle, bootstrapScriptBuilder *model.BootstrapScriptBuilder) *ServerGroupModelBuilder {
sshPublicKey := []byte("ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDF2sghZsClUBXJB4mBMIw8rb0hJWjg1Vz4eUeXwYmTdi92Gf1zNc5xISSip9Y+PWX/jJokPB7tgPnMD/2JOAKhG1bi4ZqB15pYRmbbBekVpM4o4E0dx+czbqjiAm6wlccTrINK5LYenbucAAQt19eH+D0gJwzYUK9SYz1hWnlGS+qurt2bz7rrsG73lN8E2eiNvGtIXqv3GabW/Hea3acOBgCUJQWUDTRu0OmmwxzKbFN/UpNKeRaHlCqwZWjVAsmqA8TX8LIocq7Np7MmIBwt7EpEeZJxThcmC8DEJs9ClAjD+jlLIvMPXKC3JWCPgwCLGxHjy7ckSGFCSzbyPduh")
modelContext := &model.KopsModelContext{
@ -2811,9 +2825,9 @@ func createBuilderForCluster(cluster *kops.Cluster, instanceGroups []*kops.Insta
}
return &ServerGroupModelBuilder{
OpenstackModelContext: openstackModelContext,
BootstrapScript: bootstrapScript,
Lifecycle: &clusterLifecycle,
OpenstackModelContext: openstackModelContext,
BootstrapScriptBuilder: bootstrapScriptBuilder,
Lifecycle: &clusterLifecycle,
}
}
@ -3099,18 +3113,25 @@ func compareStrings(t *testing.T, name string, actual, expected *string) {
}
}
func compareUserData(t *testing.T, actual, expected *string) {
func compareUserData(t *testing.T, actual, expected *fi.ResourceHolder) {
t.Helper()
if pointersAreBothNil(t, "UserData", actual, expected) {
return
}
if !reflect.DeepEqual(actual, expected) {
var a, e string
var err error
if actual != nil {
a = *actual
a, err = actual.AsString()
if err != nil {
t.Errorf("error getting actual: %v", err)
}
}
if expected != nil {
e = *expected
e, err = expected.AsString()
if err != nil {
t.Errorf("error getting actual: %v", err)
}
}
aLines := strings.Split(a, "\n")
eLines := strings.Split(e, "\n")
@ -3186,8 +3207,8 @@ func (n *nodeupConfigBuilder) BuildConfig(ig *kops.InstanceGroup) (*nodeup.Confi
return &nodeup.Config{}, nil
}
func mustUserdataForClusterInstance(cluster *kops.Cluster, ig *kops.InstanceGroup) string {
bootstrapScriptBuilder := &model.BootstrapScript{
func mustUserdataForClusterInstance(cluster *kops.Cluster, ig *kops.InstanceGroup) *fi.ResourceHolder {
bootstrapScriptBuilder := &model.BootstrapScriptBuilder{
NodeUpConfigBuilder: &nodeupConfigBuilder{},
NodeUpSource: map[architectures.Architecture]string{
architectures.ArchitectureAmd64: "source-amd64",
@ -3198,13 +3219,23 @@ func mustUserdataForClusterInstance(cluster *kops.Cluster, ig *kops.InstanceGrou
architectures.ArchitectureArm64: "source-hash-arm64",
},
}
startupResources, err := bootstrapScriptBuilder.ResourceNodeUp(ig, cluster)
c := &fi.ModelBuilderContext{
Tasks: make(map[string]fi.Task),
}
startupResources, err := bootstrapScriptBuilder.ResourceNodeUp(c, ig)
if err != nil {
panic(fmt.Errorf("error getting userdata: %v", err))
}
err = c.Tasks["BootstrapScript/"+ig.Name].Run(&fi.Context{Cluster: cluster})
if err != nil {
panic(fmt.Errorf("error running BootstrapScript task: %v", err))
}
userdata, err := startupResources.AsString()
if err != nil {
panic(fmt.Errorf("error converting userdata to string: %v", err))
}
return userdata
return fi.WrapResource(fi.NewStringResource(userdata))
}

View File

@ -112,9 +112,9 @@ const (
type InstanceGroupModelBuilder struct {
*model.KopsModelContext
BootstrapScript *model.BootstrapScript
Lifecycle *fi.Lifecycle
SecurityLifecycle *fi.Lifecycle
BootstrapScriptBuilder *model.BootstrapScriptBuilder
Lifecycle *fi.Lifecycle
SecurityLifecycle *fi.Lifecycle
}
var _ fi.ModelBuilder = &InstanceGroupModelBuilder{}
@ -267,7 +267,7 @@ func (b *InstanceGroupModelBuilder) buildElastigroup(c *fi.ModelBuilderContext,
}
// User data.
group.UserData, err = b.BootstrapScript.ResourceNodeUp(ig, b.Cluster)
group.UserData, err = b.BootstrapScriptBuilder.ResourceNodeUp(c, ig)
if err != nil {
return fmt.Errorf("error building user data: %v", err)
}
@ -422,7 +422,7 @@ func (b *InstanceGroupModelBuilder) buildOcean(c *fi.ModelBuilderContext, igs ..
ocean.Monitoring = ig.Spec.DetailedInstanceMonitoring
// User data.
ocean.UserData, err = b.BootstrapScript.ResourceNodeUp(ig, b.Cluster)
ocean.UserData, err = b.BootstrapScriptBuilder.ResourceNodeUp(c, ig)
if err != nil {
return fmt.Errorf("error building user data: %v", err)
}
@ -512,7 +512,7 @@ func (b *InstanceGroupModelBuilder) buildLaunchSpec(c *fi.ModelBuilderContext,
ocean.MaxSize = fi.Int64(fi.Int64Value(ocean.MaxSize) + fi.Int64Value(maxSize))
// User data.
launchSpec.UserData, err = b.BootstrapScript.ResourceNodeUp(ig, b.Cluster)
launchSpec.UserData, err = b.BootstrapScriptBuilder.ResourceNodeUp(c, ig)
if err != nil {
return fmt.Errorf("error building user data: %v", err)
}

View File

@ -72,12 +72,18 @@ type LaunchConfiguration struct {
Tags map[string]string
}
var _ fi.Task = &LaunchConfiguration{}
var _ fi.CompareWithID = &LaunchConfiguration{}
var _ fi.HasDependencies = &LaunchConfiguration{}
func (l *LaunchConfiguration) CompareWithID() *string {
return l.ID
}
func (l *LaunchConfiguration) GetDependencies(tasks map[string]fi.Task) []fi.Task {
return l.UserData.GetDependencies(tasks)
}
func (l *LaunchConfiguration) Find(c *fi.Context) (*LaunchConfiguration, error) {
if l.ScalingGroup == nil || l.ScalingGroup.ScalingGroupId == nil {
klog.V(4).Infof("ScalingGroup / ScalingGroupId not found for %s, skipping Find", fi.StringValue(l.Name))

View File

@ -573,7 +573,7 @@ func (c *ApplyClusterCmd) Run(ctx context.Context) error {
if err != nil {
return err
}
bootstrapScriptBuilder := &model.BootstrapScript{
bootstrapScriptBuilder := &model.BootstrapScriptBuilder{
NodeUpConfigBuilder: configBuilder,
NodeUpSource: c.NodeUpSource,
NodeUpSourceHash: c.NodeUpHash,
@ -586,18 +586,18 @@ func (c *ApplyClusterCmd) Run(ctx context.Context) error {
}
awsModelBuilder := &awsmodel.AutoscalingGroupModelBuilder{
AWSModelContext: awsModelContext,
BootstrapScript: bootstrapScriptBuilder,
Lifecycle: &clusterLifecycle,
SecurityLifecycle: &securityLifecycle,
AWSModelContext: awsModelContext,
BootstrapScriptBuilder: bootstrapScriptBuilder,
Lifecycle: &clusterLifecycle,
SecurityLifecycle: &securityLifecycle,
}
if featureflag.Spotinst.Enabled() {
l.Builders = append(l.Builders, &spotinstmodel.InstanceGroupModelBuilder{
KopsModelContext: modelContext,
BootstrapScript: bootstrapScriptBuilder,
Lifecycle: &clusterLifecycle,
SecurityLifecycle: &securityLifecycle,
KopsModelContext: modelContext,
BootstrapScriptBuilder: bootstrapScriptBuilder,
Lifecycle: &clusterLifecycle,
SecurityLifecycle: &securityLifecycle,
})
if featureflag.SpotinstHybrid.Enabled() {
@ -613,9 +613,9 @@ func (c *ApplyClusterCmd) Run(ctx context.Context) error {
}
l.Builders = append(l.Builders, &domodel.DropletBuilder{
DOModelContext: doModelContext,
BootstrapScript: bootstrapScriptBuilder,
Lifecycle: &clusterLifecycle,
DOModelContext: doModelContext,
BootstrapScriptBuilder: bootstrapScriptBuilder,
Lifecycle: &clusterLifecycle,
})
case kops.CloudProviderGCE:
{
@ -624,9 +624,9 @@ func (c *ApplyClusterCmd) Run(ctx context.Context) error {
}
l.Builders = append(l.Builders, &gcemodel.AutoscalingGroupModelBuilder{
GCEModelContext: gceModelContext,
BootstrapScript: bootstrapScriptBuilder,
Lifecycle: &clusterLifecycle,
GCEModelContext: gceModelContext,
BootstrapScriptBuilder: bootstrapScriptBuilder,
Lifecycle: &clusterLifecycle,
})
}
@ -637,9 +637,9 @@ func (c *ApplyClusterCmd) Run(ctx context.Context) error {
}
l.Builders = append(l.Builders, &alimodel.ScalingGroupModelBuilder{
ALIModelContext: aliModelContext,
BootstrapScript: bootstrapScriptBuilder,
Lifecycle: &clusterLifecycle,
ALIModelContext: aliModelContext,
BootstrapScriptBuilder: bootstrapScriptBuilder,
Lifecycle: &clusterLifecycle,
})
}
@ -649,9 +649,9 @@ func (c *ApplyClusterCmd) Run(ctx context.Context) error {
}
l.Builders = append(l.Builders, &openstackmodel.ServerGroupModelBuilder{
OpenstackModelContext: openstackModelContext,
BootstrapScript: bootstrapScriptBuilder,
Lifecycle: &clusterLifecycle,
OpenstackModelContext: openstackModelContext,
BootstrapScriptBuilder: bootstrapScriptBuilder,
Lifecycle: &clusterLifecycle,
})
default:

View File

@ -94,13 +94,17 @@ type LaunchConfiguration struct {
}
var _ fi.CompareWithID = &LaunchConfiguration{}
var _ fi.HasDependencies = &LaunchConfiguration{}
var _ fi.ProducesDeletions = &LaunchConfiguration{}
func (e *LaunchConfiguration) CompareWithID() *string {
return e.ID
}
func (l *LaunchConfiguration) GetDependencies(tasks map[string]fi.Task) []fi.Task {
return l.UserData.GetDependencies(tasks)
}
// findLaunchConfigurations returns matching LaunchConfigurations, sorted by CreatedTime (ascending)
func (e *LaunchConfiguration) findLaunchConfigurations(c *fi.Context) ([]*autoscaling.LaunchConfiguration, error) {
cloud := c.Cloud.(awsup.AWSCloud)

View File

@ -53,6 +53,7 @@ func TestLaunchConfigurationGarbageCollection(t *testing.T) {
ImageID: s("ami-12345678"),
InstanceType: s("m3.medium"),
SecurityGroups: []*SecurityGroup{},
UserData: fi.WrapResource(fi.NewStringResource("")),
}
return map[string]fi.Task{

View File

@ -45,12 +45,18 @@ type Droplet struct {
UserData *fi.ResourceHolder
}
var _ fi.Task = &Droplet{}
var _ fi.CompareWithID = &Droplet{}
var _ fi.HasDependencies = &Droplet{}
func (d *Droplet) CompareWithID() *string {
return d.Name
}
func (l *Droplet) GetDependencies(tasks map[string]fi.Task) []fi.Task {
return l.UserData.GetDependencies(tasks)
}
func (d *Droplet) Find(c *fi.Context) (*Droplet, error) {
cloud := c.Cloud.(*digitalocean.Cloud)

View File

@ -68,12 +68,22 @@ type InstanceTemplate struct {
ID *string
}
var _ fi.Task = &InstanceTemplate{}
var _ fi.CompareWithID = &InstanceTemplate{}
var _ fi.HasDependencies = &InstanceTemplate{}
func (e *InstanceTemplate) CompareWithID() *string {
return e.ID
}
func (l *InstanceTemplate) GetDependencies(tasks map[string]fi.Task) []fi.Task {
var deps []fi.Task
for _, resource := range l.Metadata {
deps = append(deps, resource.GetDependencies(tasks)...)
}
return deps
}
func (e *InstanceTemplate) Find(c *fi.Context) (*InstanceTemplate, error) {
cloud := c.Cloud.(gce.GCECloud)

View File

@ -41,7 +41,7 @@ type Instance struct {
ServerGroup *ServerGroup
Tags []string
Role *string
UserData *string
UserData *fi.ResourceHolder
Metadata map[string]string
AvailabilityZone *string
SecurityGroups []string
@ -49,7 +49,9 @@ type Instance struct {
Lifecycle *fi.Lifecycle
}
var _ fi.Task = &Instance{}
var _ fi.HasAddress = &Instance{}
var _ fi.HasDependencies = &Instance{}
// GetDependencies returns the dependencies of the Instance task
func (e *Instance) GetDependencies(tasks map[string]fi.Task) []fi.Task {
@ -62,6 +64,11 @@ func (e *Instance) GetDependencies(tasks map[string]fi.Task) []fi.Task {
deps = append(deps, task)
}
}
if e.UserData != nil {
deps = append(deps, e.UserData.GetDependencies(tasks)...)
}
return deps
}
@ -169,7 +176,11 @@ func (_ *Instance) RenderOpenstack(t *openstack.OpenstackAPITarget, a, e, change
SecurityGroups: e.SecurityGroups,
}
if e.UserData != nil {
opt.UserData = []byte(*e.UserData)
bytes, err := e.UserData.AsBytes()
if err != nil {
return err
}
opt.UserData = bytes
}
if e.AvailabilityZone != nil {
opt.AvailabilityZone = fi.StringValue(e.AvailabilityZone)

View File

@ -100,14 +100,14 @@ type AutoScalerDownOpts struct {
EvaluationPeriods *int
}
var _ fi.Task = &Elastigroup{}
var _ fi.CompareWithID = &Elastigroup{}
var _ fi.HasDependencies = &Elastigroup{}
func (e *Elastigroup) CompareWithID() *string {
return e.Name
}
var _ fi.HasDependencies = &Elastigroup{}
func (e *Elastigroup) GetDependencies(tasks map[string]fi.Task) []fi.Task {
var deps []fi.Task
@ -135,6 +135,10 @@ func (e *Elastigroup) GetDependencies(tasks map[string]fi.Task) []fi.Task {
}
}
if e.UserData != nil {
deps = append(deps, e.UserData.GetDependencies(tasks)...)
}
return deps
}

View File

@ -52,14 +52,14 @@ type LaunchSpec struct {
Ocean *Ocean
}
var _ fi.Task = &LaunchSpec{}
var _ fi.CompareWithID = &LaunchSpec{}
var _ fi.HasDependencies = &LaunchSpec{}
func (o *LaunchSpec) CompareWithID() *string {
return o.Name
}
var _ fi.HasDependencies = &LaunchSpec{}
func (o *LaunchSpec) GetDependencies(tasks map[string]fi.Task) []fi.Task {
var deps []fi.Task
@ -83,6 +83,10 @@ func (o *LaunchSpec) GetDependencies(tasks map[string]fi.Task) []fi.Task {
deps = append(deps, o.Ocean)
}
if o.UserData != nil {
deps = append(deps, o.UserData.GetDependencies(tasks)...)
}
return deps
}

View File

@ -64,14 +64,14 @@ type Ocean struct {
AutoScalerOpts *AutoScalerOpts
}
var _ fi.Task = &Ocean{}
var _ fi.CompareWithID = &Ocean{}
var _ fi.HasDependencies = &Ocean{}
func (o *Ocean) CompareWithID() *string {
return o.Name
}
var _ fi.HasDependencies = &Ocean{}
func (o *Ocean) GetDependencies(tasks map[string]fi.Task) []fi.Task {
var deps []fi.Task
@ -95,6 +95,10 @@ func (o *Ocean) GetDependencies(tasks map[string]fi.Task) []fi.Task {
}
}
if o.UserData != nil {
deps = append(deps, o.UserData.GetDependencies(tasks)...)
}
return deps
}