@@ -30,43 +30,14 @@ func InstanceResource() *schema.Resource {
3030 Delete : deleteInstance ,
3131 Schema : map [string ]* schema.Schema {
3232 "create_vnic_details" : {
33- Type : schema .TypeMap ,
33+ Type : schema .TypeList ,
3434 Optional : true ,
35- ForceNew : true ,
36- Elem : & schema.Resource {
37- Schema : map [string ]* schema.Schema {
38- "assign_public_ip" : {
39- Type : schema .TypeBool ,
40- Optional : true ,
41- ForceNew : true ,
42- },
43- "display_name" : {
44- Type : schema .TypeString ,
45- Optional : true ,
46- ForceNew : true ,
47- },
48- "hostname_label" : {
49- Type : schema .TypeString ,
50- Optional : true ,
51- ForceNew : true ,
52- },
53- "private_ip" : {
54- Type : schema .TypeString ,
55- Optional : true ,
56- ForceNew : true ,
57- },
58- "skip_source_dest_check" : {
59- Type : schema .TypeBool ,
60- Optional : true ,
61- ForceNew : true ,
62- },
63- "subnet_id" : {
64- Type : schema .TypeString ,
65- Required : true ,
66- ForceNew : true ,
67- },
68- },
69- },
35+ // This must be set to computed, since it's optional and required subnet_id param is being refreshed.
36+ // If this isn't computed, then that would always force a change on users who do not set create_vnic_details.
37+ Computed : true ,
38+ MaxItems : 1 ,
39+ MinItems : 1 ,
40+ Elem : createVnicDetailsSchema ,
7041 },
7142 "availability_domain" : {
7243 Type : schema .TypeString ,
@@ -260,7 +231,7 @@ func (s *InstanceResourceCrud) Create() (e error) {
260231 }
261232
262233 if rawVnic , ok := s .D .GetOk ("create_vnic_details" ); ok {
263- opts .CreateVnicOptions , e = SetCreateVnicOptions (rawVnic )
234+ opts .CreateVnicOptions = SetCreateVnicOptions (rawVnic .([] interface {}) )
264235 }
265236
266237 if e == nil {
@@ -277,12 +248,11 @@ func (s *InstanceResourceCrud) Create() (e error) {
277248}
278249
279250/*
280- * Return the public, private IP pair associated with the instance's primary Vnic .
251+ * Return the primary VNIC for this instance.
281252 *
282- * NOTE while the instance is still being created, calls to this function
283- * can return an error priort to the Vnic being attached.
253+ * Note that this may return an error during instance creation or deletion.
284254 */
285- func (s * InstanceResourceCrud ) getInstanceIPs () (public_ip string , private_ip string , e error ) {
255+ func (s * InstanceResourceCrud ) getPrimaryVnic () (vnic * baremetal. Vnic , e error ) {
286256 compartmentID := s .Resource .CompartmentID
287257
288258 opts := & baremetal.ListVnicAttachmentsOptions {}
@@ -303,7 +273,7 @@ func (s *InstanceResourceCrud) getInstanceIPs() (public_ip string, private_ip st
303273 }
304274
305275 if len (attachments ) < 1 {
306- return "" , "" , errors .New ("No VNIC attachments found." )
276+ return nil , errors .New ("No VNIC attachments found." )
307277 }
308278
309279 for _ , attachment := range attachments {
@@ -312,12 +282,12 @@ func (s *InstanceResourceCrud) getInstanceIPs() (public_ip string, private_ip st
312282
313283 // Ignore errors on GetVnic, since we might not have permissions to view some secondary VNICs.
314284 if vnic != nil && vnic .IsPrimary {
315- return vnic . PublicIPAddress , vnic . PrivateIPAddress , nil
285+ return vnic , nil
316286 }
317287 }
318288 }
319289
320- return "" , "" , errors .New ("Primary VNIC not found." )
290+ return nil , errors .New ("Primary VNIC not found." )
321291}
322292
323293func (s * InstanceResourceCrud ) Get () (e error ) {
@@ -326,25 +296,6 @@ func (s *InstanceResourceCrud) Get() (e error) {
326296 s .Resource = res
327297 }
328298
329- if e != nil {
330- return e
331- }
332-
333- // Compute instance IPs through attached Vnic
334- if s .Resource .State != baremetal .ResourceRunning {
335- return
336- }
337- public_ip , private_ip , e2 := s .getInstanceIPs ()
338- if e2 != nil {
339- log .Printf ("[DEBUG] Primary VNIC could not be found: %q (InstanceID: %q, State: %q)" , e2 , s .Resource .ID , s .Resource .State )
340- }
341-
342- if public_ip != "" {
343- s .public_ip = public_ip
344- }
345- if private_ip != "" {
346- s .private_ip = private_ip
347- }
348299 return
349300}
350301
@@ -355,6 +306,27 @@ func (s *InstanceResourceCrud) Update() (e error) {
355306 }
356307
357308 s .Resource , e = s .Client .UpdateInstance (s .D .Id (), opts )
309+ if e != nil {
310+ return
311+ }
312+
313+ // HasChange returns true for any changes within create_vnic_details.
314+ if ! s .D .HasChange ("create_vnic_details" ) {
315+ log .Printf ("[DEBUG] No changes to primary VNIC. Instance ID: %q" , s .Resource .ID )
316+ return
317+ }
318+
319+ log .Printf ("[DEBUG] Updating instance's primary VNIC. Instance ID: %q" , s .Resource .ID )
320+ vnic , e := s .getPrimaryVnic ()
321+ if e != nil {
322+ log .Printf ("[ERROR] Primary VNIC could not be found during instance update: %q (Instance ID: %q, State: %q)" , e , s .Resource .ID , s .Resource .State )
323+ return
324+ }
325+
326+ if rawVnic , ok := s .D .GetOk ("create_vnic_details" ); ok {
327+ _ , e = s .Client .UpdateVnic (vnic .ID , SetUpdateVnicOptions (rawVnic .([]interface {})))
328+ }
329+
358330 return
359331}
360332
@@ -369,8 +341,21 @@ func (s *InstanceResourceCrud) SetData() {
369341 s .D .Set ("shape" , s .Resource .Shape )
370342 s .D .Set ("state" , s .Resource .State )
371343 s .D .Set ("time_created" , s .Resource .TimeCreated .String ())
372- s .D .Set ("public_ip" , s .public_ip )
373- s .D .Set ("private_ip" , s .private_ip )
344+
345+ if s .Resource .State != baremetal .ResourceRunning {
346+ return
347+ }
348+
349+ vnic , vnicError := s .getPrimaryVnic ()
350+ if vnicError != nil {
351+ log .Printf ("[WARN] Primary VNIC could not be found during instance refresh: %q (Instance ID: %q, State: %q)" , vnicError , s .Resource .ID , s .Resource .State )
352+ return
353+ }
354+
355+ s .D .Set ("public_ip" , vnic .PublicIPAddress )
356+ s .D .Set ("private_ip" , vnic .PrivateIPAddress )
357+
358+ RefreshCreateVnicDetails (s .D , vnic )
374359}
375360
376361func (s * InstanceResourceCrud ) Delete () (e error ) {
0 commit comments