66 "regexp"
77 "time"
88
9+ "github.com/hashicorp/terraform/helper/hashcode"
910 "github.com/hashicorp/terraform/helper/schema"
1011 "github.com/joyent/gosdc/cloudapi"
1112)
@@ -108,17 +109,53 @@ func resourceMachine() *schema.Resource {
108109 Type : schema .TypeString ,
109110 Computed : true ,
110111 },
111- "networks" : {
112- Description : "desired network IDs" ,
113- Type : schema .TypeList ,
114- Optional : true ,
112+ "nic" : {
113+ Description : "network interface" ,
114+ Type : schema .TypeSet ,
115115 Computed : true ,
116- // TODO: this really should ForceNew but the Network IDs don't seem to
117- // be returned by the API, meaning if we track them here TF will replace
118- // the resource on every run.
119- // ForceNew: true,
120- Elem : & schema.Schema {
121- Type : schema .TypeString ,
116+ Optional : true ,
117+ Set : func (v interface {}) int {
118+ m := v .(map [string ]interface {})
119+ return hashcode .String (m ["network" ].(string ))
120+ },
121+ Elem : & schema.Resource {
122+ Schema : map [string ]* schema.Schema {
123+ "ip" : {
124+ Description : "NIC's IPv4 address" ,
125+ Computed : true ,
126+ Type : schema .TypeString ,
127+ },
128+ "mac" : {
129+ Description : "NIC's MAC address" ,
130+ Computed : true ,
131+ Type : schema .TypeString ,
132+ },
133+ "primary" : {
134+ Description : "Whether this is the machine's primary NIC" ,
135+ Computed : true ,
136+ Type : schema .TypeBool ,
137+ },
138+ "netmask" : {
139+ Description : "IPv4 netmask" ,
140+ Computed : true ,
141+ Type : schema .TypeString ,
142+ },
143+ "gateway" : {
144+ Description : "IPv4 gateway" ,
145+ Computed : true ,
146+ Type : schema .TypeString ,
147+ },
148+ "state" : {
149+ Description : "describes the state of the NIC (e.g. provisioning, running, or stopped)" ,
150+ Computed : true ,
151+ Type : schema .TypeString ,
152+ },
153+ "network" : {
154+ Description : "Network ID this NIC is attached to" ,
155+ Required : true ,
156+ Type : schema .TypeString ,
157+ },
158+ },
122159 },
123160 },
124161 "firewall_enabled" : {
@@ -153,6 +190,18 @@ func resourceMachine() *schema.Resource {
153190 Optional : true ,
154191 Computed : true ,
155192 },
193+
194+ // deprecated fields
195+ "networks" : {
196+ Description : "desired network IDs" ,
197+ Type : schema .TypeList ,
198+ Optional : true ,
199+ Computed : true ,
200+ Deprecated : "Networks is deprecated, please use `nic`" ,
201+ Elem : & schema.Schema {
202+ Type : schema .TypeString ,
203+ },
204+ },
156205 },
157206 }
158207}
@@ -164,6 +213,11 @@ func resourceMachineCreate(d *schema.ResourceData, meta interface{}) error {
164213 for _ , network := range d .Get ("networks" ).([]interface {}) {
165214 networks = append (networks , network .(string ))
166215 }
216+ nics := d .Get ("nic" ).(* schema.Set )
217+ for _ , nicI := range nics .List () {
218+ nic := nicI .(map [string ]interface {})
219+ networks = append (networks , nic ["network" ].(string ))
220+ }
167221
168222 metadata := map [string ]string {}
169223 for schemaName , metadataKey := range resourceMachineMetadataKeys {
@@ -221,6 +275,11 @@ func resourceMachineRead(d *schema.ResourceData, meta interface{}) error {
221275 return err
222276 }
223277
278+ nics , err := client .ListNICs (d .Id ())
279+ if err != nil {
280+ return err
281+ }
282+
224283 d .SetId (machine .Id )
225284 d .Set ("name" , machine .Name )
226285 d .Set ("type" , machine .Type )
@@ -235,9 +294,31 @@ func resourceMachineRead(d *schema.ResourceData, meta interface{}) error {
235294 d .Set ("package" , machine .Package )
236295 d .Set ("image" , machine .Image )
237296 d .Set ("primaryip" , machine .PrimaryIP )
238- d .Set ("networks" , machine .Networks )
239297 d .Set ("firewall_enabled" , machine .FirewallEnabled )
240298
299+ // create and update NICs
300+ var (
301+ machineNICs []map [string ]interface {}
302+ networks []string
303+ )
304+ for _ , nic := range nics {
305+ machineNICs = append (
306+ machineNICs ,
307+ map [string ]interface {}{
308+ "ip" : nic .IP ,
309+ "mac" : nic .MAC ,
310+ "primary" : nic .Primary ,
311+ "netmask" : nic .Netmask ,
312+ "gateway" : nic .Gateway ,
313+ "state" : nic .State ,
314+ "network" : nic .Network ,
315+ },
316+ )
317+ networks = append (networks , nic .Network )
318+ }
319+ d .Set ("nic" , machineNICs )
320+ d .Set ("networks" , networks )
321+
241322 // computed attributes from metadata
242323 for schemaName , metadataKey := range resourceMachineMetadataKeys {
243324 d .Set (schemaName , machine .Metadata [metadataKey ])
@@ -349,6 +430,41 @@ func resourceMachineUpdate(d *schema.ResourceData, meta interface{}) error {
349430 d .SetPartial ("firewall_enabled" )
350431 }
351432
433+ if d .HasChange ("nic" ) {
434+ o , n := d .GetChange ("nic" )
435+ if o == nil {
436+ o = new (schema.Set )
437+ }
438+ if n == nil {
439+ n = new (schema.Set )
440+ }
441+
442+ oldNICs := o .(* schema.Set )
443+ newNICs := o .(* schema.Set )
444+
445+ // add new NICs that are not in old NICs
446+ for _ , nicI := range newNICs .Difference (oldNICs ).List () {
447+ nic := nicI .(map [string ]interface {})
448+ fmt .Printf ("adding %+v\n " , nic )
449+ _ , err := client .AddNIC (d .Id (), nic ["network" ].(string ))
450+ if err != nil {
451+ return err
452+ }
453+ }
454+
455+ // remove old NICs that are not in new NICs
456+ for _ , nicI := range oldNICs .Difference (newNICs ).List () {
457+ nic := nicI .(map [string ]interface {})
458+ fmt .Printf ("removing %+v\n " , nic )
459+ err := client .RemoveNIC (d .Id (), nic ["mac" ].(string ))
460+ if err != nil {
461+ return err
462+ }
463+ }
464+
465+ d .SetPartial ("nic" )
466+ }
467+
352468 // metadata stuff
353469 metadata := map [string ]string {}
354470 for schemaName , metadataKey := range resourceMachineMetadataKeys {
0 commit comments