diff --git a/builder/gridscale/builder.go b/builder/gridscale/builder.go index 8cf1220..c8b69a9 100644 --- a/builder/gridscale/builder.go +++ b/builder/gridscale/builder.go @@ -85,9 +85,10 @@ func (b *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (pack ui: ui, }, &stepCreateBootStorage{ - client: client, - config: &b.config, - ui: ui, + client: client, + templateClient: client, + config: &b.config, + ui: ui, }, &stepLinkServerBootStorage{ client: client, diff --git a/builder/gridscale/step_create_boot_storage.go b/builder/gridscale/step_create_boot_storage.go index 60738f9..0b99cc4 100644 --- a/builder/gridscale/step_create_boot_storage.go +++ b/builder/gridscale/step_create_boot_storage.go @@ -11,9 +11,10 @@ import ( ) type stepCreateBootStorage struct { - client gsclient.StorageOperator - config *Config - ui packer.Ui + client gsclient.StorageOperator + templateClient gsclient.TemplateOperator + config *Config + ui packer.Ui } func (s *stepCreateBootStorage) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction { @@ -39,21 +40,31 @@ func (s *stepCreateBootStorage) Run(ctx context.Context, state multistep.StateBa state.Put("error", err) return multistep.ActionHalt } - if sshKeyUUID == "" && c.Comm.SSHPassword == "" { - ui.Error("No SSH key UUID and no SSH password are provided.") - state.Put("error", "No SSH key UUID and no SSH password are provided.") - return multistep.ActionHalt - } storage_template := gsclient.StorageTemplate{ - Hostname: c.Hostname, TemplateUUID: c.BaseTemplateUUID, } - if sshKeyUUID != "" { - storage_template.Sshkeys = []string{sshKeyUUID} + template, err := s.templateClient.GetTemplate(context.Background(), c.BaseTemplateUUID) + if err != nil { + ui.Error(fmt.Sprintf("Error getting template: %s", err)) + state.Put("error", err) + return multistep.ActionHalt } - if c.Comm.SSHPassword != "" { - storage_template.Password = c.Comm.SSHPassword - storage_template.PasswordType = gsclient.PlainPasswordType + // Check if template is public, if so, either ssh key or password and hostname is required. + // If template is private, ssh key or password will be ignored. + if !template.Properties.Private { + storage_template.Hostname = c.Hostname + if sshKeyUUID == "" && c.Comm.SSHPassword == "" { + ui.Error("No SSH key UUID and no SSH password are provided.") + state.Put("error", "No SSH key UUID and no SSH password are provided.") + return multistep.ActionHalt + } + if sshKeyUUID != "" { + storage_template.Sshkeys = []string{sshKeyUUID} + } + if c.Comm.SSHPassword != "" { + storage_template.Password = c.Comm.SSHPassword + storage_template.PasswordType = gsclient.PlainPasswordType + } } storageCreateReq.Template = &storage_template } diff --git a/builder/gridscale/step_create_boot_storage_test.go b/builder/gridscale/step_create_boot_storage_test.go index 01ce421..c7f265b 100644 --- a/builder/gridscale/step_create_boot_storage_test.go +++ b/builder/gridscale/step_create_boot_storage_test.go @@ -110,9 +110,10 @@ func Test_stepCreateBootStorage_Cleanup(t *testing.T) { func Test_stepCreateBootStorage_Run(t *testing.T) { type fields struct { - client gsclient.StorageOperator - config *Config - ui packer.Ui + client gsclient.StorageOperator + templateClient gsclient.TemplateOperator + config *Config + ui packer.Ui } type args struct { ctx context.Context @@ -128,7 +129,8 @@ func Test_stepCreateBootStorage_Run(t *testing.T) { { name: "success", fields: fields{ - client: StorageOperatorMock{}, + client: StorageOperatorMock{}, + templateClient: TemplateOperatorMock{}, config: produceTestConfig(map[string]interface{}{ "server_name": "success", }), @@ -145,7 +147,8 @@ func Test_stepCreateBootStorage_Run(t *testing.T) { { name: "API call fail", fields: fields{ - client: StorageOperatorMock{}, + client: StorageOperatorMock{}, + templateClient: TemplateOperatorMock{}, config: produceTestConfig(map[string]interface{}{ "server_name": "fail", }), @@ -162,7 +165,8 @@ func Test_stepCreateBootStorage_Run(t *testing.T) { { name: "No SSH key UUID detected", fields: fields{ - client: StorageOperatorMock{}, + client: StorageOperatorMock{}, + templateClient: TemplateOperatorMock{}, config: produceTestConfig(map[string]interface{}{ "server_name": "success", }), @@ -179,7 +183,8 @@ func Test_stepCreateBootStorage_Run(t *testing.T) { { name: "cannot convert ssh_key_uuid to string", fields: fields{ - client: StorageOperatorMock{}, + client: StorageOperatorMock{}, + templateClient: TemplateOperatorMock{}, config: produceTestConfig(map[string]interface{}{ "server_name": "success", }), @@ -195,9 +200,10 @@ func Test_stepCreateBootStorage_Run(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { s := &stepCreateBootStorage{ - client: tt.fields.client, - config: tt.fields.config, - ui: tt.fields.ui, + client: tt.fields.client, + templateClient: tt.fields.templateClient, + config: tt.fields.config, + ui: tt.fields.ui, } if got := s.Run(tt.args.ctx, tt.args.state); got != tt.want { t.Errorf("stepCreateBootStorage_Run() = %v, want %v", got, tt.want)