@@ -117,6 +117,7 @@ func resourceLoadBalancer() *schema.Resource {
117
117
"listener" : & schema.Schema {
118
118
Type : schema .TypeList ,
119
119
Required : true ,
120
+ MaxItems : 1 ,
120
121
Elem : & schema.Resource {
121
122
Schema : map [string ]* schema.Schema {
122
123
"id" : & schema.Schema {
@@ -156,6 +157,19 @@ func resourceLoadBalancer() *schema.Resource {
156
157
Type : schema .TypeString ,
157
158
Optional : true ,
158
159
},
160
+ "insert_x_forwarded" : & schema.Schema {
161
+ Type : schema .TypeBool ,
162
+ Optional : true ,
163
+ },
164
+ "secret_id" : & schema.Schema {
165
+ Type : schema .TypeString ,
166
+ Optional : true ,
167
+ },
168
+ "sni_secret_id" : & schema.Schema {
169
+ Type : schema .TypeList ,
170
+ Elem : & schema.Schema {Type : schema .TypeString },
171
+ Optional : true ,
172
+ },
159
173
},
160
174
},
161
175
},
@@ -190,7 +204,18 @@ func resourceLoadBalancerCreate(ctx context.Context, d *schema.ResourceData, m i
190
204
Certificate : l ["certificate" ].(string ),
191
205
CertificateChain : l ["certificate_chain" ].(string ),
192
206
PrivateKey : l ["private_key" ].(string ),
207
+ InsertXForwarded : l ["insert_x_forwarded" ].(bool ),
208
+ SecretID : l ["secret_id" ].(string ),
209
+ }
210
+ sniSecretIDRaw := l ["sni_secret_id" ].([]interface {})
211
+ if len (sniSecretIDRaw ) != 0 {
212
+ sniSecretID := make ([]string , len (sniSecretIDRaw ))
213
+ for i , s := range sniSecretIDRaw {
214
+ sniSecretID [i ] = s .(string )
215
+ }
216
+ opts .SNISecretID = sniSecretID
193
217
}
218
+
194
219
listenersOpts [i ] = opts
195
220
}
196
221
@@ -261,38 +286,30 @@ func resourceLoadBalancerRead(ctx context.Context, d *schema.ResourceData, m int
261
286
fields := []string {"flavor" , "vip_network_id" , "vip_subnet_id" }
262
287
revertState (d , & fields )
263
288
264
- currentListeners := d .Get ("listener" ).([]interface {})
265
- newListeners := make ([]map [string ]interface {}, len (lb .Listeners ))
289
+ cl := d .Get ("listener" ).([]interface {})[0 ]
266
290
listenersClient , err := CreateClient (provider , d , LBListenersPoint , versionPointV1 )
267
291
if err != nil {
268
292
return diag .FromErr (err )
269
293
}
270
294
271
- for i , l := range lb .Listeners {
295
+ currentL := cl .(map [string ]interface {})
296
+ for _ , l := range lb .Listeners {
272
297
listener , err := listeners .Get (listenersClient , l .ID ).Extract ()
273
298
if err != nil {
274
299
return diag .FromErr (err )
275
300
}
276
301
277
- for _ , cl := range currentListeners {
278
- currentL , ok := cl .(map [string ]interface {})
279
- if currentL != nil && ok {
280
- if currentL ["name" ].(string ) == listener .Name {
281
- currentL ["id" ] = listener .ID
282
- newListeners [i ] = currentL
283
- break
284
- }
285
- } else {
286
- newListeners [i ] = map [string ]interface {}{
287
- "id" : listener .ID ,
288
- "name" : listener .Name ,
289
- "protocol" : listener .Protocol .String (),
290
- "protocol_port" : listener .ProtocolPort ,
291
- }
292
- }
302
+ if listener .ProtocolPort == currentL ["protocol_port" ].(int ) && listener .Protocol .String () == currentL ["protocol" ] {
303
+ currentL ["id" ] = listener .ID
304
+ currentL ["name" ] = listener .Name
305
+ currentL ["protocol" ] = listener .Protocol .String ()
306
+ currentL ["protocol_port" ] = listener .ProtocolPort
307
+ currentL ["secret_id" ] = listener .SecretID
308
+ currentL ["sni_secret_id" ] = listener .SNISecretID
309
+ break
293
310
}
294
311
}
295
- if err := d .Set ("listener" , newListeners ); err != nil {
312
+ if err := d .Set ("listener" , [] interface {}{ currentL } ); err != nil {
296
313
diag .FromErr (err )
297
314
}
298
315
@@ -322,6 +339,99 @@ func resourceLoadBalancerUpdate(ctx context.Context, d *schema.ResourceData, m i
322
339
d .Set ("last_updated" , time .Now ().Format (time .RFC850 ))
323
340
}
324
341
342
+ if d .HasChange ("listener" ) {
343
+ client , err := CreateClient (provider , d , LBListenersPoint , versionPointV1 )
344
+ if err != nil {
345
+ return diag .FromErr (err )
346
+ }
347
+
348
+ oldListenerRaw , newListenerRaw := d .GetChange ("listener" )
349
+ oldListener := oldListenerRaw .([]interface {})[0 ].(map [string ]interface {})
350
+ newListener := newListenerRaw .([]interface {})[0 ].(map [string ]interface {})
351
+
352
+ listenerID := oldListener ["id" ].(string )
353
+ if oldListener ["protocol" ].(string ) != newListener ["protocol" ].(string ) ||
354
+ oldListener ["protocol_port" ].(int ) != newListener ["protocol_port" ].(int ) {
355
+ //if protocol or port changed listener need to be recreated
356
+ //delete at first
357
+ results , err := listeners .Delete (client , listenerID ).Extract ()
358
+ if err != nil {
359
+ return diag .FromErr (err )
360
+ }
361
+
362
+ taskID := results .Tasks [0 ]
363
+ _ , err = tasks .WaitTaskAndReturnResult (client , taskID , true , LBListenerCreateTimeout , func (task tasks.TaskID ) (interface {}, error ) {
364
+ _ , err := listeners .Get (client , listenerID ).Extract ()
365
+ if err == nil {
366
+ return nil , fmt .Errorf ("cannot delete LBListener with ID: %s" , listenerID )
367
+ }
368
+ switch err .(type ) {
369
+ case gcorecloud.ErrDefault404 :
370
+ return nil , nil
371
+ default :
372
+ return nil , err
373
+ }
374
+ })
375
+ if err != nil {
376
+ return diag .FromErr (err )
377
+ }
378
+
379
+ //create new one
380
+ opts := listeners.CreateOpts {
381
+ Name : newListener ["name" ].(string ),
382
+ Protocol : types .ProtocolType (newListener ["protocol" ].(string )),
383
+ ProtocolPort : newListener ["protocol_port" ].(int ),
384
+ LoadBalancerID : d .Id (),
385
+ InsertXForwarded : newListener ["insert_x_forwarded" ].(bool ),
386
+ SecretID : newListener ["secret_id" ].(string ),
387
+ }
388
+ sniSecretIDRaw := newListener ["sni_secret_id" ].([]interface {})
389
+ if len (sniSecretIDRaw ) != 0 {
390
+ sniSecretID := make ([]string , len (sniSecretIDRaw ))
391
+ for i , s := range sniSecretIDRaw {
392
+ sniSecretID [i ] = s .(string )
393
+ }
394
+ opts .SNISecretID = sniSecretID
395
+ }
396
+
397
+ results , err = listeners .Create (client , opts ).Extract ()
398
+ if err != nil {
399
+ return diag .FromErr (err )
400
+ }
401
+
402
+ taskID = results .Tasks [0 ]
403
+ _ , err = tasks .WaitTaskAndReturnResult (client , taskID , true , LBListenerCreateTimeout , func (task tasks.TaskID ) (interface {}, error ) {
404
+ taskInfo , err := tasks .Get (client , string (task )).Extract ()
405
+ if err != nil {
406
+ return nil , fmt .Errorf ("cannot get task with ID: %s. Error: %w" , task , err )
407
+ }
408
+ listenerID , err := listeners .ExtractListenerIDFromTask (taskInfo )
409
+ if err != nil {
410
+ return nil , fmt .Errorf ("cannot retrieve LBListener ID from task info: %w" , err )
411
+ }
412
+ return listenerID , nil
413
+ })
414
+ if err != nil {
415
+ return diag .FromErr (err )
416
+ }
417
+ } else {
418
+ //update
419
+ opts := listeners.UpdateOpts {
420
+ Name : newListener ["name" ].(string ),
421
+ SecretID : newListener ["secret_id" ].(string ),
422
+ }
423
+ sniSecretIDRaw := newListener ["sni_secret_id" ].([]interface {})
424
+ sniSecretID := make ([]string , len (sniSecretIDRaw ))
425
+ for i , s := range sniSecretIDRaw {
426
+ sniSecretID [i ] = s .(string )
427
+ }
428
+ opts .SNISecretID = sniSecretID
429
+ if _ , err := listeners .Update (client , listenerID , opts ).Extract (); err != nil {
430
+ return diag .FromErr (err )
431
+ }
432
+ }
433
+ }
434
+
325
435
log .Println ("[DEBUG] Finish LoadBalancer updating" )
326
436
return resourceLoadBalancerRead (ctx , d , m )
327
437
}
0 commit comments