Skip to content

Commit

Permalink
Added IPAssociation resource and use of host record (#10)
Browse files Browse the repository at this point in the history
This commit also contains changes in the way IP gets assigned.
Previously the IP assigned was of type fixedaddress due to few
constraint we are using host record .Necessary changes in other
resources have been made to use host record
  • Loading branch information
saiprasannasastry authored and jkraj committed Apr 24, 2018
1 parent 7a6d989 commit ac20bdc
Show file tree
Hide file tree
Showing 5 changed files with 183 additions and 61 deletions.
1 change: 1 addition & 0 deletions infoblox/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ func Provider() terraform.ResourceProvider {
"infoblox_network": resourceNetwork(),
"infoblox_network_view": resourceNetworkView(),
"infoblox_ip_allocation": resourceIPAllocation(),
"infoblox_ip_association": resourceIPAssociation(),
},
ConfigureFunc: providerConfigure,
}
Expand Down
72 changes: 29 additions & 43 deletions infoblox/resourceIPAllocation.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,11 @@ func resourceIPAllocation() *schema.Resource {
DefaultFunc: schema.EnvDefaultFunc("networkViewName", "default"),
Description: "Network view name available in Nios server.",
},
"network_name": &schema.Schema{
"host_name": &schema.Schema{
Type: schema.TypeString,
Optional: true,
DefaultFunc: schema.EnvDefaultFunc("networkName", nil),
Description: "The name of the network.",
Required: true,
DefaultFunc: schema.EnvDefaultFunc("hostName", nil),
Description: "The name of the record.",
},
"cidr": &schema.Schema{
Type: schema.TypeString,
Expand All @@ -42,21 +42,21 @@ func resourceIPAllocation() *schema.Resource {
},
"mac_addr": &schema.Schema{
Type: schema.TypeString,
Required: true,
Optional: true,
DefaultFunc: schema.EnvDefaultFunc("macaddr", nil),
Description: "mac address of your instance in cloud.",
},
"vm_id": &schema.Schema{
Type: schema.TypeString,
Required: true,
Optional: true,
DefaultFunc: schema.EnvDefaultFunc("vmid", nil),
Description: "Virtual Machine name.",
Description: "instance name.",
},
"tenant_id": &schema.Schema{
Type: schema.TypeString,
Required: true,
DefaultFunc: schema.EnvDefaultFunc("tenantID", nil),
Description: "Unique identifier of your instance in cloud.",
Description: "Unique identifier of your tenant in cloud.",
},
"gateway": &schema.Schema{
Type: schema.TypeString,
Expand All @@ -69,10 +69,15 @@ func resourceIPAllocation() *schema.Resource {
}
}

//We are using creation of host record for IPAM purposes for the reason that
//if we create a fixed address,t has mac address as a required parameter and
//a mac address is not generated before provisioning of vm hence we use create
//host record method used below
func resourceIPAllocationRequest(d *schema.ResourceData, m interface{}) error {
log.Printf("[DEBUG] %s: Beginning to request a next free IP from a required network block", resourceIPAllocationIDString(d))

networkViewName := d.Get("network_view_name").(string)
recordName := d.Get("host_name").(string)
ipAddr := d.Get("ip_addr").(string)
cidr := d.Get("cidr").(string)
macAddr := d.Get("mac_addr").(string)
Expand All @@ -94,34 +99,31 @@ func resourceIPAllocationRequest(d *schema.ResourceData, m interface{}) error {
}
}

ipAddrObj, err := objMgr.AllocateIP(networkViewName, cidr, ipAddr, macAddr, vmID)
hostrecordObj, err := objMgr.CreateHostRecordWithoutDNS(recordName, networkViewName, cidr, ipAddr, macAddr, vmID)
if err != nil {
return fmt.Errorf("Error allocating IP from network block(%s): %s", cidr, err)
}

d.Set("gateway", gatewayIP.IPAddress)
d.Set("ipAddr", ipAddrObj.IPAddress)
d.Set("ip_addr", hostrecordObj.Ipv4Addrs[0].Ipv4Addr)
// TODO what happens in case of a VM have 2 network interfaces.
d.SetId(vmID)
d.SetId(hostrecordObj.Ref)

log.Printf("[DEBUG] %s:completing Request of IP from required network block", resourceIPAllocationIDString(d))
log.Printf("[DEBUG] %s:completing Request of IP from required network block", resourceIPAllocationIDString(d))
return nil
}

func resourceIPAllocationGet(d *schema.ResourceData, m interface{}) error {

log.Printf("[DEBUG] %s:Reading the required IP from network block", resourceIPAllocationIDString(d))
log.Printf("[DEBUG] %s:Reading the required IP from network block", resourceIPAllocationIDString(d))

networkViewName := d.Get("network_view_name").(string)
tenantID := d.Get("tenant_id").(string)
ipAddr := d.Get("ip_addr").(string)
cidr := d.Get("cidr").(string)
macAddr := d.Get("mac_addr").(string)
connector := m.(*ibclient.Connector)

objMgr := ibclient.NewObjectManager(connector, "terraform", tenantID)

_, err := objMgr.GetFixedAddress(networkViewName, cidr, ipAddr, macAddr)
_, err := objMgr.GetHostRecord(d.Id())
if err != nil {
return fmt.Errorf("Error getting IP from network block(%s): %s", cidr, err)
}
Expand All @@ -132,55 +134,39 @@ func resourceIPAllocationGet(d *schema.ResourceData, m interface{}) error {

func resourceIPAllocationUpdate(d *schema.ResourceData, m interface{}) error {

log.Printf("[DEBUG] %s: Updating the Parameters of the allocated IP", resourceIPAllocationIDString(d))
log.Printf("[DEBUG] %s: Updating the Parameters of the allocated IP in the specified network block", resourceIPAllocationIDString(d))

networkViewName := d.Get("network_view_ame").(string)
networkName := d.Get("network_name").(string)
ipAddr := d.Get("ip_addr").(string)
cidr := d.Get("cidr").(string)
macAddr := d.Get("mac_addr").(string)
vmID := d.Get("vm_id").(string)
tenantID := d.Get("tenant_id").(string)

vmID := d.Get("vm_id").(string)
connector := m.(*ibclient.Connector)

objMgr := ibclient.NewObjectManager(connector, "terraform", tenantID)

ref, err := objMgr.GetFixedAddress(networkViewName, networkName, ipAddr, "")
if err != nil {
return fmt.Errorf("GetFixedAddress error from network(%s):%s", cidr, err)
}

_, err = objMgr.UpdateFixedAddress(ref.Ref, macAddr, vmID)
if err != nil {
return fmt.Errorf("UpdateFixedAddress error from network block(%s):%s", cidr, err)
}
hostRecordObj, _ := objMgr.GetHostRecord(d.Id())
IPAddrObj, _ := objMgr.GetIpAddressFromHostRecord(*hostRecordObj)
objMgr.UpdateHostRecordWithoutDNS(d.Id(), IPAddrObj, macAddr, vmID)

log.Printf("[DEBUG] %s: Updation of Parameters of allocated IP complete", resourceIPAllocationIDString(d))
log.Printf("[DEBUG] %s: Updation of Parameters of allocated IP complete in the specified network block", resourceIPAllocationIDString(d))
return nil
}

func resourceIPAllocationRelease(d *schema.ResourceData, m interface{}) error {

log.Printf("[DEBUG] %s: Beginning Release of an allocated IP", resourceIPAllocationIDString(d))
log.Printf("[DEBUG] %s: Beginning Release of an allocated IP in the specified network block", resourceIPAllocationIDString(d))

networkViewName := d.Get("network_view_name").(string)
ipAddr := d.Get("ip_addr").(string)
cidr := d.Get("cidr").(string)
macAddr := d.Get("mac_addr").(string)
tenantID := d.Get("tenant_id").(string)
connector := m.(*ibclient.Connector)

objMgr := ibclient.NewObjectManager(connector, "terraform", tenantID)

_, err := objMgr.ReleaseIP(networkViewName, cidr, ipAddr, macAddr)
_, err := objMgr.DeleteHostRecord(d.Id())
if err != nil {
return fmt.Errorf("Error Releasing IP from network(%s): %s", cidr, err)
return fmt.Errorf("Error Releasing IP from network block having reference (%s): %s", d.Id(), err)
}

d.SetId("")

log.Printf("[DEBUG] %s: Finishing Release of allocated IP", resourceIPAllocationIDString(d))
log.Printf("[DEBUG] %s: Finishing Release of allocated IP in the specified network block", resourceIPAllocationIDString(d))
return nil
}

Expand Down
142 changes: 142 additions & 0 deletions infoblox/resourceIPAssociation.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
package infoblox

import (
"fmt"
"github.com/hashicorp/terraform/helper/schema"
"github.com/infobloxopen/infoblox-go-client"
"log"
)

func resourceIPAssociation() *schema.Resource {
return &schema.Resource{
Create: resourceIPAssociationCreate,
Update: resourceIPAssociationUpdate,
Delete: resourceIPAssociationDelete,
Read: resourceIPAssociationRead,

Schema: map[string]*schema.Schema{
"network_view_name": &schema.Schema{
Type: schema.TypeString,
Optional: true,
DefaultFunc: schema.EnvDefaultFunc("network_view_name", "default"),
Description: "Network view name available in Nios server.",
},
"host_name": &schema.Schema{
Type: schema.TypeString,
Optional: true,
DefaultFunc: schema.EnvDefaultFunc("host_name", nil),
Description: "The name of the record.",
},
"cidr": &schema.Schema{
Type: schema.TypeString,
Required: true,
DefaultFunc: schema.EnvDefaultFunc("net_address", nil),
Description: "Give the address in cidr format.",
},
"ip_addr": &schema.Schema{
Type: schema.TypeString,
Optional: true,
DefaultFunc: schema.EnvDefaultFunc("ipaddr", nil),
Description: "IP address of your instance in cloud.",
Computed: true,
},
"mac_addr": &schema.Schema{
Type: schema.TypeString,
Optional: true,
DefaultFunc: schema.EnvDefaultFunc("macaddr", nil),
Description: "mac address of your instance in cloud.",
},
"vm_id": &schema.Schema{
Type: schema.TypeString,
Optional: true,
DefaultFunc: schema.EnvDefaultFunc("vmid", nil),
Description: "instance name.",
},
"tenant_id": &schema.Schema{
Type: schema.TypeString,
Required: true,
DefaultFunc: schema.EnvDefaultFunc("tenant_id", nil),
Description: "Unique identifier of your tenant in cloud.",
},
},
}
}

//This method has an update call for the reason that,we are creating
//a host record which doesnt have the details of the mac address
//at the beginigand we are using this update call to update the mac address
//of the record after the VM has been provisined.It is in the create method
//because for this resource we are doing association instead of allocation.
func resourceIPAssociationCreate(d *schema.ResourceData, m interface{}) error {
log.Printf("[DEBUG] %s: Beginning Association of IP address in specified network block", resourceIPAssociationIDString(d))

networkViewName := d.Get("network_view_name").(string)
recordName := d.Get("host_name").(string)
ipAddr := d.Get("ip_addr").(string)
cidr := d.Get("cidr").(string)
macAddr := d.Get("mac_addr").(string)
tenantID := d.Get("tenant_id").(string)
vmID := d.Get("vm_id").(string)

connector := m.(*ibclient.Connector)

objMgr := ibclient.NewObjectManager(connector, "terraform", tenantID)

hostRecordObj, err := objMgr.GetHostRecordtWithoutDNS(recordName, networkViewName, cidr, ipAddr)
if err != nil {
return fmt.Errorf("GetHostAddress error from network block(%s):%s", cidr, err)
}
_, err = objMgr.UpdateHostRecordWithoutDNS(hostRecordObj.Ref, ipAddr, macAddr, vmID)
if err != nil {
return fmt.Errorf("UpdateHostAddress error from network block(%s):%s", cidr, err)
}

d.SetId(hostRecordObj.Ref)
log.Printf("[DEBUG] %s:completing Association of IP address in specified network block", resourceIPAssociationIDString(d))
return nil
}

func resourceIPAssociationUpdate(d *schema.ResourceData, m interface{}) error {
return nil
}

func resourceIPAssociationRead(d *schema.ResourceData, m interface{}) error {
return nil
}

//we are updating the record with an empty mac address after the vm has been
//destroyed because if we implement the delete hostrecord method here then there
//will be a conflict of resources
func resourceIPAssociationDelete(d *schema.ResourceData, m interface{}) error {
log.Printf("[DEBUG] %s: Beginning Reassociation of IP address in specified network block", resourceIPAssociationIDString(d))

ipAddr := d.Get("ip_addr").(string)
tenantID := d.Get("tenant_id").(string)

connector := m.(*ibclient.Connector)

objMgr := ibclient.NewObjectManager(connector, "terraform", tenantID)

_, err := objMgr.UpdateHostRecordWithoutDNS(d.Id(), ipAddr, "00:00:00:00:00:00", "")
if err != nil {
return fmt.Errorf("Error Releasing IP from network block having reference (%s): %s", d.Id(), err)
}

d.SetId("")

log.Printf("[DEBUG] %s: Finishing Release of allocated IP in specified network block", resourceIPAssociationIDString(d))

return nil
}

type resourceIPAssociationIDStringInterface interface {
Id() string
}

func resourceIPAssociationIDString(d resourceIPAssociationIDStringInterface) string {
id := d.Id()
if id == "" {
id = "<new resource>"
}
return fmt.Sprintf("infoblox_mac_allocation (ID = %s)", id)
}
25 changes: 9 additions & 16 deletions infoblox/resourceNetwork.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,19 +25,19 @@ func resourceNetwork() *schema.Resource {
Type: schema.TypeString,
Required: true,
DefaultFunc: schema.EnvDefaultFunc("networkName", nil),
Description: "The name of the network.",
Description: "The name of your network block.",
},
"cidr": &schema.Schema{
Type: schema.TypeString,
Required: true,
DefaultFunc: schema.EnvDefaultFunc("net_address", nil),
Description: "Give the address in cidr format.",
Description: "Give the network block in cidr format.",
},
"tenant_id": &schema.Schema{
Type: schema.TypeString,
Required: true,
DefaultFunc: schema.EnvDefaultFunc("tenantID", nil),
Description: "Unique identifier of your instance in cloud.",
Description: "Unique identifier of your tenant in cloud.",
},
},
}
Expand All @@ -56,9 +56,9 @@ func resourceNetworkCreate(d *schema.ResourceData, m interface{}) error {

nwname, err := objMgr.CreateNetwork(networkViewName, cidr, networkName)
if err != nil {
return fmt.Errorf("Creation of network failed in network view (%s) : %s", networkViewName, err)
return fmt.Errorf("Creation of network block failed in network view (%s) : %s", networkViewName, err)
}
d.SetId(nwname.Cidr)
d.SetId(nwname.Ref)

log.Printf("[DEBUG] %s: Creation on network block complete", resourceNetworkIDString(d))
return nil
Expand All @@ -67,15 +67,14 @@ func resourceNetworkRead(d *schema.ResourceData, m interface{}) error {
log.Printf("[DEBUG] %s: Reading the required network block", resourceNetworkIDString(d))

networkViewName := d.Get("network_view_name").(string)
cidr := d.Get("cidr").(string)
tenantID := d.Get("tenant_id").(string)
connector := m.(*ibclient.Connector)

objMgr := ibclient.NewObjectManager(connector, "terraform", tenantID)

_, err := objMgr.GetNetwork(networkViewName, cidr, nil)
_, err := objMgr.GetNetworkwithref(d.Id())
if err != nil {
return fmt.Errorf("Getting Network from network view (%s) failed : %s", networkViewName, err)
return fmt.Errorf("Getting Network block from network view (%s) failed : %s", networkViewName, err)
}

log.Printf("[DEBUG] %s: Completed reading network block", resourceNetworkIDString(d))
Expand All @@ -90,20 +89,14 @@ func resourceNetworkDelete(d *schema.ResourceData, m interface{}) error {
log.Printf("[DEBUG] %s: Beginning Deletion of network block", resourceNetworkIDString(d))

networkViewName := d.Get("network_view_name").(string)
cidr := d.Get("cidr").(string)
tenantID := d.Get("tenant_id").(string)
connector := m.(*ibclient.Connector)

objMgr := ibclient.NewObjectManager(connector, "terraform", tenantID)

ref, err := objMgr.GetNetwork(networkViewName, cidr, nil)
if err != nil {
return fmt.Errorf("Getting Network failed from network view(%s) for deletion : %s", networkViewName, err)
}

_, err = objMgr.DeleteNetwork(ref.Ref, d.Get("network_view_name").(string))
_, err := objMgr.DeleteNetwork(d.Id(), d.Get("network_view_name").(string))
if err != nil {
return fmt.Errorf("Deletion of Network failed from network view(%s) for deletion : %s", networkViewName, err)
return fmt.Errorf("Deletion of Network block failed from network view(%s) for deletion : %s", networkViewName, err)
}
d.SetId("")

Expand Down
Loading

0 comments on commit ac20bdc

Please sign in to comment.