diff --git a/README.md b/README.md
index 06bd90776..3e036a4e8 100644
--- a/README.md
+++ b/README.md
@@ -1,59 +1,59 @@
-# Terraform Provider for Infoblox
+
+# Terraform Provider for Infoblox
+Terraform provider plugin to integrate with Infoblox Network Identity Operating System [NIOS].
-## Requirements
-* [Terraform](https://www.terraform.io/downloads.html) 0.14.x
-* [Go](https://golang.org/doc/install) 1.15.x or 1.16.x (to build the provider plugin)
-* CNA License need to be installed on NIOS. If CNA is not installed then following default EA's should be added in NIOS side:
- * VM Name :: String Type
- * VM ID :: String Type
- * Tenant ID :: String Type
- * CMP Type :: String Type
- * Cloud API Owned :: List Type (Values True, False)
- * Network Name :: String Type
+The latest version of Infoblox NIOS provider is [v1.1.1](https://github.com/infobloxopen/terraform-provider-infoblox/releases/tag/v1.1.1)
## Building the Provider
-
+* Install and set apt environment variables [Golang](https://golang.org/doc/install) 1.16.x
+* Clone the repo and build it
```sh
$ git clone https://github.com/infobloxopen/terraform-provider-infoblox
$ cd terraform-provider-infoblox
$ make build
```
-## Using the Provider
-If you're building the provider, follow the instructions to [install it as a plugin](https://www.terraform.io/docs/plugins/basics.html#installing-a-plugin). After the build is complete, copy the `terraform-provider-infoblox` binary into the same path as your terraform binary. After placing it into your plugins directory, run `terraform init` to initialize it.
-
## Developing the Provider
-If you wish to work on the provider, you'll first need Go installed on your machine (version 1.15.x or 1.16.x is required).
+If you wish to work on the provider, follow the above steps to build it.
-To compile the provider, run the following steps:
-```sh
-$ make build
-...
-$ ./terraform-provider-infoblox
-...
-```
-To test the provider, you can simply run `make test`.
+To test the provider and to run the full suite of acceptance tests run below commands accordingly,
```sh
$ make test
-```
-
-In order to run the full suite of acceptance tests `make testacc`.
-```sh
$ make testacc
```
+
+## Using the Provider
+* To use the plugin install v0.14.x [Terraform](https://www.terraform.io/downloads.html)
+* If you're building the provider, follow the instructions to [install it as a plugin](https://www.terraform.io/docs/cli/config/config-file.html#development-overrides-for-provider-developers).
+* Once the build is completed, set the `terraform-provider-infoblox` binary file location appropriately in in `dev_overrides`.
+
+## NIOS Requirements
+* Plugin can be used without a CNA license and does not mandate to specify any EAs.
+
+* If Cloud Network Automation[CNA] License is installed on NIOS and has a Cloud Platform[CP] member attached. Make sure to have below mandatory EAs in .tf file if non mandatory cloud EAs(like "VM Name", "VM ID", "Network Name") are used.
+ * Tenant ID :: String Type
+ * CMP Type :: String Type
+ * Cloud API Owned :: List Type (Values True, False)
+
## Features of Provider
### Resource
+Create, Update and Delete of below resources is supported along with comment and EAs fields.
+* IPv4 & IPv6 Network Container
+* IPv4 & IPv6 Network
+* Allocation & Deallocation of IPv4 or IPv6 address.
+* Association & Disassociation of IPv4 or IPv6 address for a VM.
+
+Below resources are still under development and incomplete.
* Creation & Deletion of Network View in NIOS appliance
-* Creation & Deletion of IPv4 Network with comment field in NIOS appliance
-* Allocation & Deallocation of IPv4 address from an IPv4 Network
-* Association & Disassociation of IPv4 Address for a VM
* Creation and Deletion of A, CNAME, Host, and PTR records
### Data Source
-* Supports Data Source for IPv4 Network
-* Support Data Source for A and CNAME records
+Data Sources for below records are supported.
+* IPv4 Network
+* A Record
+* CNAME Record
## Disclaimer
To use the provider for DNS purposes, a parent (i.e. zone) must already exist. The plugin does not support the creation of zones.
-while running acceptance tests create a 10.0.0.0/24 network under default network view and create a reservation for 10.0.0.2 IP
+While running acceptance tests create a 10.0.0.0/24 network under default network view and create a reservation for 10.0.0.2 IP
diff --git a/examples/README.md b/examples/README.md
new file mode 100644
index 000000000..90a9516a1
--- /dev/null
+++ b/examples/README.md
@@ -0,0 +1,3 @@
+
+* The Terraform configuration files under `v0.14` path are written and tested on Terraform v0.14 version and are actively maintained.
+* The terraform configuration files under `archived` directory are of older version and are not maintained actively.
\ No newline at end of file
diff --git a/examples/AWS/ARecord/aws.tf b/examples/archived/AWS/ARecord/aws.tf
similarity index 100%
rename from examples/AWS/ARecord/aws.tf
rename to examples/archived/AWS/ARecord/aws.tf
diff --git a/examples/AWS/ARecord/infoblox.tf b/examples/archived/AWS/ARecord/infoblox.tf
similarity index 100%
rename from examples/AWS/ARecord/infoblox.tf
rename to examples/archived/AWS/ARecord/infoblox.tf
diff --git a/examples/AWS/CNAMERecord/aws.tf b/examples/archived/AWS/CNAMERecord/aws.tf
similarity index 100%
rename from examples/AWS/CNAMERecord/aws.tf
rename to examples/archived/AWS/CNAMERecord/aws.tf
diff --git a/examples/AWS/CNAMERecord/infoblox.tf b/examples/archived/AWS/CNAMERecord/infoblox.tf
similarity index 100%
rename from examples/AWS/CNAMERecord/infoblox.tf
rename to examples/archived/AWS/CNAMERecord/infoblox.tf
diff --git a/examples/AWS/FixedAddress/aws.tf b/examples/archived/AWS/FixedAddress/aws.tf
similarity index 100%
rename from examples/AWS/FixedAddress/aws.tf
rename to examples/archived/AWS/FixedAddress/aws.tf
diff --git a/examples/AWS/FixedAddress/infoblox.tf b/examples/archived/AWS/FixedAddress/infoblox.tf
similarity index 100%
rename from examples/AWS/FixedAddress/infoblox.tf
rename to examples/archived/AWS/FixedAddress/infoblox.tf
diff --git a/examples/AWS/NextAvailableNetwork/aws.tf b/examples/archived/AWS/NextAvailableNetwork/aws.tf
similarity index 100%
rename from examples/AWS/NextAvailableNetwork/aws.tf
rename to examples/archived/AWS/NextAvailableNetwork/aws.tf
diff --git a/examples/AWS/NextAvailableNetwork/infoblox.tf b/examples/archived/AWS/NextAvailableNetwork/infoblox.tf
similarity index 100%
rename from examples/AWS/NextAvailableNetwork/infoblox.tf
rename to examples/archived/AWS/NextAvailableNetwork/infoblox.tf
diff --git a/examples/AWS/PTRRecord/aws.tf b/examples/archived/AWS/PTRRecord/aws.tf
similarity index 100%
rename from examples/AWS/PTRRecord/aws.tf
rename to examples/archived/AWS/PTRRecord/aws.tf
diff --git a/examples/AWS/PTRRecord/infoblox.tf b/examples/archived/AWS/PTRRecord/infoblox.tf
similarity index 100%
rename from examples/AWS/PTRRecord/infoblox.tf
rename to examples/archived/AWS/PTRRecord/infoblox.tf
diff --git a/examples/AWS/README.md b/examples/archived/AWS/README.md
similarity index 100%
rename from examples/AWS/README.md
rename to examples/archived/AWS/README.md
diff --git a/examples/Azure/NextAvailableNetwork/azure.tf b/examples/archived/Azure/NextAvailableNetwork/azure.tf
similarity index 100%
rename from examples/Azure/NextAvailableNetwork/azure.tf
rename to examples/archived/Azure/NextAvailableNetwork/azure.tf
diff --git a/examples/Azure/NextAvailableNetwork/infoblox.tf b/examples/archived/Azure/NextAvailableNetwork/infoblox.tf
similarity index 100%
rename from examples/Azure/NextAvailableNetwork/infoblox.tf
rename to examples/archived/Azure/NextAvailableNetwork/infoblox.tf
diff --git a/examples/Azure/README.md b/examples/archived/Azure/README.md
similarity index 100%
rename from examples/Azure/README.md
rename to examples/archived/Azure/README.md
diff --git a/examples/Azure/infoblox.tf b/examples/archived/Azure/infoblox.tf
similarity index 100%
rename from examples/Azure/infoblox.tf
rename to examples/archived/Azure/infoblox.tf
diff --git a/examples/Azure/vm.tf b/examples/archived/Azure/vm.tf
similarity index 100%
rename from examples/Azure/vm.tf
rename to examples/archived/Azure/vm.tf
diff --git a/examples/VMware/FixedAddress/infoblox.tf b/examples/archived/VMware/FixedAddress/infoblox.tf
similarity index 100%
rename from examples/VMware/FixedAddress/infoblox.tf
rename to examples/archived/VMware/FixedAddress/infoblox.tf
diff --git a/examples/VMware/FixedAddress/vm.tf b/examples/archived/VMware/FixedAddress/vm.tf
similarity index 100%
rename from examples/VMware/FixedAddress/vm.tf
rename to examples/archived/VMware/FixedAddress/vm.tf
diff --git a/examples/VMware/HostRecord/infoblox.tf b/examples/archived/VMware/HostRecord/infoblox.tf
similarity index 100%
rename from examples/VMware/HostRecord/infoblox.tf
rename to examples/archived/VMware/HostRecord/infoblox.tf
diff --git a/examples/VMware/HostRecord/vm.tf b/examples/archived/VMware/HostRecord/vm.tf
similarity index 100%
rename from examples/VMware/HostRecord/vm.tf
rename to examples/archived/VMware/HostRecord/vm.tf
diff --git a/examples/VMware/NextAvailableNetwork/infoblox.tf b/examples/archived/VMware/NextAvailableNetwork/infoblox.tf
similarity index 100%
rename from examples/VMware/NextAvailableNetwork/infoblox.tf
rename to examples/archived/VMware/NextAvailableNetwork/infoblox.tf
diff --git a/examples/VMware/NextAvailableNetwork/vm.tf b/examples/archived/VMware/NextAvailableNetwork/vm.tf
similarity index 100%
rename from examples/VMware/NextAvailableNetwork/vm.tf
rename to examples/archived/VMware/NextAvailableNetwork/vm.tf
diff --git a/examples/VMware/README.md b/examples/archived/VMware/README.md
similarity index 100%
rename from examples/VMware/README.md
rename to examples/archived/VMware/README.md
diff --git a/examples/VMware/multiple/infoblox.tf b/examples/archived/VMware/multiple/infoblox.tf
similarity index 100%
rename from examples/VMware/multiple/infoblox.tf
rename to examples/archived/VMware/multiple/infoblox.tf
diff --git a/examples/VMware/multiple/vm.tf b/examples/archived/VMware/multiple/vm.tf
similarity index 100%
rename from examples/VMware/multiple/vm.tf
rename to examples/archived/VMware/multiple/vm.tf
diff --git a/examples/datasources/azurerm/README.md b/examples/archived/datasources/azurerm/README.md
similarity index 100%
rename from examples/datasources/azurerm/README.md
rename to examples/archived/datasources/azurerm/README.md
diff --git a/examples/datasources/azurerm/main.tf b/examples/archived/datasources/azurerm/main.tf
similarity index 100%
rename from examples/datasources/azurerm/main.tf
rename to examples/archived/datasources/azurerm/main.tf
diff --git a/examples/v0.14/AWS/AllocationAndAssociation/aws.tf b/examples/v0.14/AWS/AllocationAndAssociation/aws.tf
new file mode 100644
index 000000000..cbf7b8073
--- /dev/null
+++ b/examples/v0.14/AWS/AllocationAndAssociation/aws.tf
@@ -0,0 +1,57 @@
+# Region being used to create the resources
+provider "aws" {
+ region = "us-west-1"
+}
+
+# Create a Virtual Private Cloud
+resource "aws_vpc" "vpc" {
+ cidr_block = "10.0.0.0/16"
+ # Allocates /56 IPv6 CIDR block From Amazon Global Unicast Address to VPC
+ assign_generated_ipv6_cidr_block = true
+ tags = {
+ Name = "tf-vpc"
+ }
+}
+
+# Create a Subnet
+resource "aws_subnet" "subnet" {
+ vpc_id = aws_vpc.vpc.id
+ cidr_block = infoblox_ipv4_network.ipv4_network.cidr
+ ipv6_cidr_block = infoblox_ipv6_network.ipv6_network.cidr
+ availability_zone = "us-west-1a"
+ assign_ipv6_address_on_creation = false
+ map_public_ip_on_launch = false
+
+ tags = {
+ Name = "tf-subnet"
+ Subnet = "tf-subnet"
+ }
+}
+
+
+#Create Network Interface
+resource "aws_network_interface" "ni" {
+ subnet_id = aws_subnet.subnet.id
+ private_ips = [infoblox_ipv4_allocation.ipv4_allocation.ip_addr]
+ ipv6_addresses = [infoblox_ipv6_allocation.ipv6_allocation.ip_addr]
+
+ tags = {
+ Name = "tf-ni"
+ }
+}
+
+# Create AWS Instance
+resource "aws_instance" "ec2-instance" {
+ # This ami is for us-west-1, change to Amazon Linux AMI for your region
+ ami = "ami-03130878b60947df3"
+ instance_type = "t2.micro"
+
+ network_interface {
+ network_interface_id = aws_network_interface.ni.id
+ device_index = 0
+ }
+
+ tags = {
+ Name = "tf-ec2-instance"
+ }
+}
diff --git a/examples/v0.14/AWS/AllocationAndAssociation/infoblox.tf b/examples/v0.14/AWS/AllocationAndAssociation/infoblox.tf
new file mode 100644
index 000000000..485808d1e
--- /dev/null
+++ b/examples/v0.14/AWS/AllocationAndAssociation/infoblox.tf
@@ -0,0 +1,167 @@
+terraform {
+ # Required providers block for Terraform v0.14.7
+ required_providers {
+ aws = {
+ source = "hashicorp/aws"
+ version = "~> 3.0"
+ }
+ infoblox = {
+ source = "terraform-providers/infoblox"
+ version = ">= 1.0"
+ }
+ }
+}
+
+# Create a network container in Infoblox Grid
+resource "infoblox_ipv4_network_container" "IPv4_nw_c" {
+ network_view_name="default"
+
+ cidr = aws_vpc.vpc.cidr_block
+ comment = "tf IPv4 network container"
+ extensible_attributes = jsonencode({
+ "Tenant ID" = "tf-plugin"
+ Location = "Test loc."
+ Site = "Test site"
+ })
+}
+
+resource "infoblox_ipv6_network_container" "IPv6_nw_c" {
+ network_view_name="default"
+
+ cidr = aws_vpc.vpc.ipv6_cidr_block
+ comment = "tf IPv6 network container"
+ extensible_attributes = jsonencode({
+ "Tenant ID" = "tf-plugin"
+ Location = "Test loc."
+ Site = "Test site"
+ })
+}
+
+
+# Allocate a network in Infoblox Grid under provided parent CIDR
+resource "infoblox_ipv4_network" "ipv4_network"{
+ network_view_name = "default"
+
+ parent_cidr = infoblox_ipv4_network_container.IPv4_nw_c.cidr
+ allocate_prefix_len = 24
+ reserve_ip = 2
+
+ comment = "tf IPv4 network"
+ extensible_attributes = jsonencode({
+ "Tenant ID" = "tf-plugin"
+ "Network Name" = "ipv4-tf-network"
+ Location = "Test loc."
+ Site = "Test site"
+ })
+}
+
+resource "infoblox_ipv6_network" "ipv6_network"{
+ network_view_name = "default"
+
+ parent_cidr = infoblox_ipv6_network_container.IPv6_nw_c.cidr
+ allocate_prefix_len = 64
+ reserve_ipv6 = 3
+
+ comment = "tf IPv6 network"
+ extensible_attributes = jsonencode({
+ "Tenant ID" = "tf-plugin"
+ "Network Name" = "ipv6-tf-network"
+ Location = "Test loc."
+ Site = "Test site"
+ })
+}
+
+
+# Allocate IP from network
+resource "infoblox_ipv4_allocation" "ipv4_allocation"{
+ network_view_name= "default"
+ cidr = infoblox_ipv4_network.ipv4_network.cidr
+ host_name = "test"
+
+ #Create Host Record with DNS and DHCP flags
+ #dns_view="default"
+ #zone="aws.com"
+ #enable_dns = "false"
+ #enable_dhcp = "false"
+
+ comment = "tf IPv4 allocation"
+ extensible_attributes = jsonencode({
+ "Tenant ID" = "tf-plugin"
+ "Network Name" = "ipv4-tf-network"
+ "VM Name" = "tf-ec2-instance"
+ Location = "Test loc."
+ Site = "Test site"
+ })
+}
+
+resource "infoblox_ipv6_allocation" "ipv6_allocation" {
+ network_view_name= "default"
+ cidr = infoblox_ipv6_network.ipv6_network.cidr
+ duid = "00:00:00:00:00:00:00:00"
+ host_name = "test"
+
+ #Create Host Record with DNS and DHCP flags
+ #dns_view="default"
+ #zone="aws.com"
+ #enable_dns = "false"
+ #enable_dhcp = "false"
+
+ comment = "tf IPv6 allocation"
+ extensible_attributes = jsonencode({
+ "Tenant ID" = "tf-plugin"
+ "Network Name" = "ipv6-tf-network"
+ "VM Name" = "tf-ec2-instance-ipv6"
+ Location = "Test loc."
+ Site = "Test site"
+ })
+}
+
+
+# Update Grid with VM data
+resource "infoblox_ipv4_association" "ipv4_associate"{
+ network_view_name = "default"
+ cidr = infoblox_ipv4_network.ipv4_network.cidr
+ ip_addr = infoblox_ipv4_allocation.ipv4_allocation.ip_addr
+ mac_addr = aws_network_interface.ni.mac_address
+ host_name = "test"
+
+ #Create Host Record with DNS and DHCP flags
+ #dns_view="default"
+ #zone="aws.com"
+ #enable_dns = "false"
+ #enable_dhcp = "false"
+
+ comment = "tf IPv4 Association"
+ extensible_attributes = jsonencode({
+ "Tenant ID" = "tf-plugin"
+ "Network Name" = "ipv6-tf-network"
+ "VM Name" = "tf-ec2-instance"
+ "VM ID" = aws_instance.ec2-instance.id
+ Location = "Test loc."
+ Site = "Test site"
+ })
+}
+
+resource "infoblox_ipv6_association" "ipv6_associate"{
+ network_view_name = "default"
+ cidr = infoblox_ipv6_network.ipv6_network.cidr
+ ip_addr = infoblox_ipv6_allocation.ipv6_allocation.ip_addr
+ duid = aws_network_interface.ni.mac_address
+ host_name = "test"
+
+ #Create Host Record with DNS and DHCP flags
+ #dns_view="default"
+ #zone="aws.com"
+ #enable_dns = "false"
+ #enable_dhcp = "false"
+
+ comment = "tf IPv6 Association"
+ extensible_attributes = jsonencode({
+ "Tenant ID" = "tf-plugin"
+ "Network Name" = "ipv6-tf-network"
+ "VM Name" = "tf-ec2-instance-ipv6"
+ "VM ID" = aws_instance.ec2-instance.id
+ Location = "Test loc."
+ Site = "Test site"
+ })
+}
diff --git a/examples/v0.14/AWS/Network/aws.tf b/examples/v0.14/AWS/Network/aws.tf
new file mode 100644
index 000000000..0f6ed5ecc
--- /dev/null
+++ b/examples/v0.14/AWS/Network/aws.tf
@@ -0,0 +1,29 @@
+# Region being used to create the resources
+provider "aws" {
+ region = "us-west-1"
+}
+
+# Create a Virtual Private Cloud
+resource "aws_vpc" "vpc" {
+ cidr_block = "10.0.0.0/16"
+ # Allocates /56 IPv6 CIDR block From Amazon Global Unicast Address to VPC
+ assign_generated_ipv6_cidr_block = true
+ tags = {
+ Name = "tf-vpc"
+ }
+}
+
+# Create a Subnet
+resource "aws_subnet" "subnet" {
+ vpc_id = aws_vpc.vpc.id
+ cidr_block = infoblox_ipv4_network.ipv4_network.cidr
+ ipv6_cidr_block = infoblox_ipv6_network.ipv6_network.cidr
+ availability_zone = "us-west-1a"
+ assign_ipv6_address_on_creation = false
+ map_public_ip_on_launch = false
+
+ tags = {
+ Name = "tf-subnet"
+ Subnet = "tf-subnet"
+ }
+}
\ No newline at end of file
diff --git a/examples/v0.14/AWS/Network/infoblox.tf b/examples/v0.14/AWS/Network/infoblox.tf
new file mode 100644
index 000000000..7af198e20
--- /dev/null
+++ b/examples/v0.14/AWS/Network/infoblox.tf
@@ -0,0 +1,72 @@
+terraform {
+ # Required providers block for Terraform v0.14.7
+ required_providers {
+ aws = {
+ source = "hashicorp/aws"
+ version = "~> 3.0"
+ }
+ infoblox = {
+ source = "terraform-providers/infoblox"
+ version = ">= 1.0"
+ }
+ }
+}
+
+# Create a network container in Infoblox Grid
+resource "infoblox_ipv4_network_container" "IPv4_nw_c" {
+ network_view_name="default"
+
+ cidr = aws_vpc.vpc.cidr_block
+ comment = "tf IPv4 network container"
+ extensible_attributes = jsonencode({
+ "Tenant ID" = "tf-plugin"
+ "Location" = "Test loc."
+ "Site" = "Test site"
+ })
+}
+
+resource "infoblox_ipv6_network_container" "IPv6_nw_c" {
+ network_view_name="default"
+
+ cidr = aws_vpc.vpc.ipv6_cidr_block
+ comment = "tf IPv6 network container"
+ extensible_attributes = jsonencode({
+ "Tenant ID" = "tf-plugin"
+ "Location" = "Test loc."
+ "Site" = "Test site"
+ })
+}
+
+
+# Allocate a network in Infoblox Grid under provided parent CIDR
+resource "infoblox_ipv4_network" "ipv4_network"{
+ network_view_name = "default"
+
+ parent_cidr = infoblox_ipv4_network_container.IPv4_nw_c.cidr
+ allocate_prefix_len = 24
+ reserve_ip = 2
+
+ comment = "tf IPv4 network"
+ extensible_attributes = jsonencode({
+ "Tenant ID" = "tf-plugin"
+ "Network Name" = "ipv4-tf-network"
+ "Location" = "Test loc."
+ "Site" = "Test site"
+ })
+}
+
+resource "infoblox_ipv6_network" "ipv6_network"{
+ network_view_name = "default"
+
+ parent_cidr = infoblox_ipv6_network_container.IPv6_nw_c.cidr
+ allocate_prefix_len = 64
+ reserve_ipv6 = 3
+
+ comment = "tf IPv6 network"
+ extensible_attributes = jsonencode({
+ "Tenant ID" = "tf-plugin"
+ "Network Name" = "ipv6-tf-network"
+ "Location" = "Test loc."
+ "Site" = "Test site"
+ })
+}
\ No newline at end of file
diff --git a/examples/v0.14/AWS/NetworkContainer/aws.tf b/examples/v0.14/AWS/NetworkContainer/aws.tf
new file mode 100644
index 000000000..78077fca6
--- /dev/null
+++ b/examples/v0.14/AWS/NetworkContainer/aws.tf
@@ -0,0 +1,14 @@
+# Region being used to create the resources
+provider "aws" {
+ region = "us-west-1"
+}
+
+# Create a Virtual Private Cloud
+resource "aws_vpc" "vpc" {
+ cidr_block = "10.0.0.0/16"
+ # Allocates /56 IPv6 CIDR block From Amazon Global Unicast Address to VPC
+ assign_generated_ipv6_cidr_block = true
+ tags = {
+ Name = "tf-vpc"
+ }
+}
\ No newline at end of file
diff --git a/examples/v0.14/AWS/NetworkContainer/infoblox.tf b/examples/v0.14/AWS/NetworkContainer/infoblox.tf
new file mode 100644
index 000000000..99b925277
--- /dev/null
+++ b/examples/v0.14/AWS/NetworkContainer/infoblox.tf
@@ -0,0 +1,36 @@
+terraform {
+ # Required providers block for Terraform v0.14.7
+ required_providers {
+ aws = {
+ source = "hashicorp/aws"
+ version = "~> 3.0"
+ }
+ infoblox = {
+ source = "terraform-providers/infoblox"
+ version = ">= 1.0"
+ }
+ }
+}
+
+# Create a network container in Infoblox Grid
+resource "infoblox_ipv4_network_container" "IPv4_nw_c" {
+ network_view_name="default"
+ cidr = aws_vpc.vpc.cidr_block
+ comment = "tf IPv4 network container"
+ extensible_attributes = jsonencode({
+ "Tenant ID" = "tf-plugin"
+ "Location" = "Test loc."
+ "Site" = "Test site"
+ })
+}
+
+resource "infoblox_ipv6_network_container" "IPv6_nw_c" {
+ network_view_name="default"
+ cidr = aws_vpc.vpc.ipv6_cidr_block
+ comment = "tf IPv6 network container"
+ extensible_attributes = jsonencode({
+ "Tenant ID" = "tf-plugin"
+ "Location" = "Test loc."
+ "Site" = "Test site"
+ })
+}
\ No newline at end of file
diff --git a/examples/v0.14/AWS/NextAvailableNetwork/aws.tf b/examples/v0.14/AWS/NextAvailableNetwork/aws.tf
index ef4393176..f88c247c7 100644
--- a/examples/v0.14/AWS/NextAvailableNetwork/aws.tf
+++ b/examples/v0.14/AWS/NextAvailableNetwork/aws.tf
@@ -1,11 +1,13 @@
# Region being used to create the resources
provider "aws" {
- region = "us-east-1"
+ region = "us-west-1"
}
# Create a Virtual Private Cloud
resource "aws_vpc" "vpc" {
- cidr_block = "20.0.0.0/16"
+ cidr_block = "10.0.0.0/16"
+ # Allocates /56 IPv6 CIDR block From Amazon Global Unicast Address to VPC
+ assign_generated_ipv6_cidr_block = true
tags = {
Name = "tf-vpc"
}
@@ -14,39 +16,14 @@ resource "aws_vpc" "vpc" {
# Create a Subnet
resource "aws_subnet" "subnet" {
vpc_id = aws_vpc.vpc.id
- cidr_block = infoblox_network.ib_network.cidr
- availability_zone = "us-east-1b"
+ cidr_block = infoblox_ipv4_network.ipv4_network.cidr
+ ipv6_cidr_block = infoblox_ipv6_network.ipv6_network.cidr
+ availability_zone = "us-west-1a"
+ assign_ipv6_address_on_creation = false
+ map_public_ip_on_launch = false
tags = {
Name = "tf-subnet"
Subnet = "tf-subnet"
}
-}
-
-# Create Network Interface
-resource "aws_network_interface" "ni" {
- subnet_id = aws_subnet.subnet.id
- private_ips = [infoblox_ip_allocation.ib_ip_allocation.ip_addr]
-
- tags = {
- Name = "tf-ni"
- }
-}
-
-# Create AWS Instance
-resource "aws_instance" "ec2-instance" {
- # This ami is for us-west-1, change to Amazon Linux AMI for your region
- #ami = "ami-03130878b60947df3"
- ami = "ami-0915bcb5fa77e4892"
- instance_type = "t2.micro"
-
- network_interface {
- network_interface_id = aws_network_interface.ni.id
- device_index = 0
- }
-
- tags = {
- Name = infoblox_ip_allocation.ib_ip_allocation.vm_name
- }
-}
-
+}
\ No newline at end of file
diff --git a/examples/v0.14/AWS/NextAvailableNetwork/infoblox.tf b/examples/v0.14/AWS/NextAvailableNetwork/infoblox.tf
index 95ab8dcea..1fca53c0c 100644
--- a/examples/v0.14/AWS/NextAvailableNetwork/infoblox.tf
+++ b/examples/v0.14/AWS/NextAvailableNetwork/infoblox.tf
@@ -1,4 +1,3 @@
-# Creates next available network from a given parent CIDR in NIOS grid
terraform {
# Required providers block for Terraform v0.14.7
required_providers {
@@ -13,32 +12,61 @@ terraform {
}
}
+# Create a network container in Infoblox Grid
+resource "infoblox_ipv4_network_container" "IPv4_nw_c" {
+ network_view_name="default"
+
+ cidr = aws_vpc.vpc.cidr_block
+ comment = "tf IPv4 network container"
+ extensible_attributes = jsonencode({
+ "Tenant ID" = "tf-plugin"
+ "Location" = "Test loc."
+ "Site" = "Test site"
+ })
+}
+
+resource "infoblox_ipv6_network_container" "IPv6_nw_c" {
+ network_view_name="default"
+
+ cidr = aws_vpc.vpc.ipv6_cidr_block
+ comment = "tf IPv6 network container"
+ extensible_attributes = jsonencode({
+ "Tenant ID" = "tf-plugin"
+ "Location" = "Test loc."
+ "Site" = "Test site"
+ })
+}
+
+
# Allocate a network in Infoblox Grid under provided parent CIDR
-resource "infoblox_network" "ib_network"{
+resource "infoblox_ipv4_network" "ipv4_network"{
network_view_name = "default"
- network_name = "tf-network"
- tenant_id = "tf-AWS-tenant"
+
+ parent_cidr = infoblox_ipv4_network_container.IPv4_nw_c.cidr
allocate_prefix_len = 24
- parent_cidr = "20.0.0.0/16"
reserve_ip = 2
-}
-# Allocate IP from network
-resource "infoblox_ip_allocation" "ib_ip_allocation"{
- network_view_name= "default"
- vm_name = "tf-ec2-instance"
- cidr = infoblox_network.ib_network.cidr
- tenant_id = "tf-AWS-tenant"
+ comment = "tf IPv4 network"
+ extensible_attributes = jsonencode({
+ "Tenant ID" = "tf-plugin"
+ "Network Name" = "ipv4-tf-network"
+ "Location" = "Test loc."
+ "Site" = "Test site"
+ })
}
-# Update Grid with VM data
-resource "infoblox_ip_association" "ib_ip_associate"{
+resource "infoblox_ipv6_network" "ipv6_network"{
network_view_name = "default"
- vm_name = infoblox_ip_allocation.ib_ip_allocation.vm_name
- cidr = infoblox_network.ib_network.cidr
- mac_addr = aws_network_interface.ni.mac_address
- ip_addr = infoblox_ip_allocation.ib_ip_allocation.ip_addr
- vm_id = aws_instance.ec2-instance.id
- tenant_id = "tf-AWS-tenant"
-}
+ parent_cidr = infoblox_ipv6_network_container.IPv6_nw_c.cidr
+ allocate_prefix_len = 64
+ reserve_ipv6 = 3
+
+ comment = "tf IPv6 network"
+ extensible_attributes = jsonencode({
+ "Tenant ID" = "tf-plugin"
+ "Network Name" = "ipv6-tf-network"
+ "Location" = "Test loc."
+ "Site" = "Test site"
+ })
+}
\ No newline at end of file
diff --git a/examples/v0.14/AWS/README.md b/examples/v0.14/AWS/README.md
index 3f4098a29..910258957 100644
--- a/examples/v0.14/AWS/README.md
+++ b/examples/v0.14/AWS/README.md
@@ -10,7 +10,10 @@ Install AWS CLI. Use AWS Configure command to configure Access Key ID and Secret
```
#Using the templates for below use cases.
+- NetworkContainer : Create IPv4/IPv6 Network Containers
+- Network : Create IPv4/IPv6 Network
- NextAvailableNetwork : Get next available network from a given parent CIDR of a prefix length.
+- AllocationAndAssociation : Assign an IPv4 and IPv6 address to an AWS instance and get its MAC address synced at NIOS
### Note
```
diff --git a/examples/v0.14/Azure/NetworkContainer/IPv4/azure.tf b/examples/v0.14/Azure/NetworkContainer/IPv4/azure.tf
new file mode 100644
index 000000000..0953ffd17
--- /dev/null
+++ b/examples/v0.14/Azure/NetworkContainer/IPv4/azure.tf
@@ -0,0 +1,83 @@
+provider "azurerm" {
+ features {}
+}
+
+resource "azurerm_resource_group" "rg1" {
+ name = "${local.res_prefix}_rg1"
+ location = "ukwest"
+}
+
+resource "azurerm_virtual_network" "vnet1" {
+ location = "ukwest"
+ resource_group_name = azurerm_resource_group.rg1.name
+
+ name = "${local.res_prefix}_vnet1"
+ address_space = [infoblox_ipv4_network_container.v4nc_1.cidr]
+}
+
+resource "azurerm_subnet" "net1" {
+ resource_group_name = azurerm_resource_group.rg1.name
+ virtual_network_name = azurerm_virtual_network.vnet1.name
+
+ name = "${local.res_prefix}_net1"
+ address_prefixes =[infoblox_ipv4_network.subnet1.cidr]
+}
+
+resource "azurerm_public_ip" "pub_addr1" {
+ resource_group_name = azurerm_resource_group.rg1.name
+ location = "ukwest"
+
+ name = "${local.res_prefix}_pub_addr1"
+ allocation_method = "Dynamic"
+ domain_name_label = "a132"
+}
+
+resource "azurerm_network_interface" "ni1" {
+ resource_group_name = azurerm_resource_group.rg1.name
+ location = "ukwest"
+
+ name = "${local.res_prefix}_ni1"
+ ip_configuration {
+ name = "${local.res_prefix}_ipconfiguration1"
+ subnet_id = azurerm_subnet.net1.id
+ private_ip_address_allocation = "Static"
+ private_ip_address =infoblox_ipv4_allocation.alloc1.ip_addr
+
+ public_ip_address_id = azurerm_public_ip.pub_addr1.id
+ }
+}
+
+resource "azurerm_virtual_machine" "vm1" {
+ resource_group_name = azurerm_resource_group.rg1.name
+ location = "ukwest"
+
+ name = "${local.res_prefix}_vm1"
+ network_interface_ids = [azurerm_network_interface.ni1.id]
+ primary_network_interface_id = azurerm_network_interface.ni1.id
+ vm_size = "Standard_A6"
+ delete_os_disk_on_termination = true
+ delete_data_disks_on_termination = true
+
+ storage_image_reference {
+ publisher = "Canonical"
+ offer = "UbuntuServer"
+ sku = "16.04-LTS"
+ version = "latest"
+ }
+
+ storage_os_disk {
+ name = "main_storage"
+ caching = "ReadWrite"
+ create_option = "FromImage"
+ }
+
+ os_profile {
+ computer_name = "ubuntu"
+ admin_username = "ubuntu"
+ admin_password="JKLhdsa&^52128"
+ }
+
+ os_profile_linux_config {
+ disable_password_authentication = false
+ }
+}
diff --git a/examples/v0.14/Azure/NetworkContainer/IPv4/infoblox.tf b/examples/v0.14/Azure/NetworkContainer/IPv4/infoblox.tf
new file mode 100644
index 000000000..4d180e07b
--- /dev/null
+++ b/examples/v0.14/Azure/NetworkContainer/IPv4/infoblox.tf
@@ -0,0 +1,43 @@
+resource "infoblox_network_view" "nv1" {
+ tenant_id = local.tenant_id
+ network_view_name=local.net_view
+}
+
+resource "infoblox_ipv4_network_container" "v4nc_1" {
+ network_view_name=infoblox_network_view.nv1.network_view_name
+ cidr = "10.0.0.0/16"
+ comment = "new network container"
+ extensible_attributes = jsonencode({
+ "Location" = "Test loc."
+ "Site" = "Test site"
+ "Tenant ID" = local.tenant_id
+ })
+}
+
+resource "infoblox_ipv4_network" "subnet1"{
+ network_view_name=infoblox_network_view.nv1.network_view_name
+ allocate_prefix_len = 24
+ parent_cidr = infoblox_ipv4_network_container.v4nc_1.cidr
+ reserve_ip=3
+ extensible_attributes = jsonencode({
+ "Tenant ID" = local.tenant_id
+ "Network Name" = "${local.res_prefix}_subnet1"
+ })
+}
+
+resource "infoblox_ipv4_allocation" "alloc1" {
+ network_view_name=infoblox_network_view.nv1.network_view_name
+ cidr=infoblox_ipv4_network.subnet1.cidr
+ host_name = "test"
+
+ #Create Host Record with DNS and DHCP flags
+ #dns_view="default"
+ #zone="aws.com"
+ #enable_dns = "false"
+ #enable_dhcp = "false"
+
+ extensible_attributes = jsonencode({
+ "Tenant ID" = local.tenant_id
+ "VM Name" = "${local.res_prefix}_vm1"
+ })
+}
diff --git a/examples/v0.14/Azure/NetworkContainer/IPv4/locals.tf b/examples/v0.14/Azure/NetworkContainer/IPv4/locals.tf
new file mode 120000
index 000000000..1b032e65b
--- /dev/null
+++ b/examples/v0.14/Azure/NetworkContainer/IPv4/locals.tf
@@ -0,0 +1 @@
+../locals.tf
\ No newline at end of file
diff --git a/examples/v0.14/Azure/NetworkContainer/IPv4/terraform.tf b/examples/v0.14/Azure/NetworkContainer/IPv4/terraform.tf
new file mode 120000
index 000000000..fdbf0eba0
--- /dev/null
+++ b/examples/v0.14/Azure/NetworkContainer/IPv4/terraform.tf
@@ -0,0 +1 @@
+../terraform.tf
\ No newline at end of file
diff --git a/examples/v0.14/Azure/NetworkContainer/IPv6/azure.tf b/examples/v0.14/Azure/NetworkContainer/IPv6/azure.tf
new file mode 100644
index 000000000..c1ae1fc61
--- /dev/null
+++ b/examples/v0.14/Azure/NetworkContainer/IPv6/azure.tf
@@ -0,0 +1,102 @@
+provider "azurerm" {
+ features {}
+}
+
+resource "azurerm_resource_group" "rg1" {
+ name = "${local.res_prefix}_rg1"
+ location = "ukwest"
+}
+
+resource "azurerm_virtual_network" "vnet1" {
+ location = "ukwest"
+ resource_group_name = azurerm_resource_group.rg1.name
+
+ name = "${local.res_prefix}_vnet1"
+ address_space = [
+ infoblox_ipv4_network_container.nc_1.cidr,
+ infoblox_ipv6_network_container.nc_2.cidr]
+}
+
+resource "azurerm_subnet" "net1" {
+ resource_group_name = azurerm_resource_group.rg1.name
+ virtual_network_name = azurerm_virtual_network.vnet1.name
+
+ name = "${local.res_prefix}_net1"
+ address_prefixes =[
+ infoblox_ipv4_network.subnet1.cidr,
+ infoblox_ipv6_network.subnet2.cidr]
+}
+
+resource "azurerm_public_ip" "pub_addr1" {
+ resource_group_name = azurerm_resource_group.rg1.name
+ location = "ukwest"
+
+ name = "${local.res_prefix}_pub_addr1"
+ allocation_method = "Dynamic"
+ domain_name_label = "a132"
+ ip_version = "IPv4"
+}
+
+resource "azurerm_network_interface" "ni1" {
+ resource_group_name = azurerm_resource_group.rg1.name
+ location = "ukwest"
+
+ name = "${local.res_prefix}_ni1"
+
+ ip_configuration {
+ name = "${local.res_prefix}_ipconfiguration1"
+ subnet_id = azurerm_subnet.net1.id
+ private_ip_address_allocation = "Static"
+ private_ip_address_version = "IPv6"
+ private_ip_address = infoblox_ipv6_allocation.alloc2.ip_addr
+ }
+
+ ip_configuration {
+ primary = true
+ name = "${local.res_prefix}_ipconfiguration2"
+ subnet_id = azurerm_subnet.net1.id
+ private_ip_address_allocation = "Static"
+ private_ip_address = infoblox_ipv4_allocation.alloc1.ip_addr
+ public_ip_address_id = azurerm_public_ip.pub_addr1.id
+ }
+}
+
+resource "azurerm_virtual_machine" "vm1" {
+ resource_group_name = azurerm_resource_group.rg1.name
+ location = "ukwest"
+
+ name = "${local.res_prefix}_vm1"
+ network_interface_ids = [azurerm_network_interface.ni1.id]
+ primary_network_interface_id = azurerm_network_interface.ni1.id
+ vm_size = "Standard_A6"
+ delete_os_disk_on_termination = true
+ delete_data_disks_on_termination = true
+
+ storage_image_reference {
+ publisher = "Canonical"
+ offer = "UbuntuServer"
+ sku = "16.04-LTS"
+ version = "latest"
+ }
+
+ storage_os_disk {
+ name = "main_storage"
+ caching = "ReadWrite"
+ create_option = "FromImage"
+ }
+
+ os_profile {
+ computer_name = "ubuntu"
+ admin_username = "ubuntu"
+ admin_password="JKLhdsa&^52128"
+ }
+
+ os_profile_linux_config {
+ disable_password_authentication = false
+ }
+}
+
+locals {
+ vm_mac_addr = azurerm_network_interface.ni1.mac_address
+ vm_id = azurerm_virtual_machine.vm1.id
+}
diff --git a/examples/v0.14/Azure/NetworkContainer/IPv6/infoblox.tf b/examples/v0.14/Azure/NetworkContainer/IPv6/infoblox.tf
new file mode 100644
index 000000000..244b6957a
--- /dev/null
+++ b/examples/v0.14/Azure/NetworkContainer/IPv6/infoblox.tf
@@ -0,0 +1,147 @@
+resource "infoblox_network_view" "nv1" {
+ tenant_id = local.tenant_id
+ network_view_name=local.net_view
+}
+
+resource "infoblox_ipv4_network_container" "nc_1" {
+ network_view_name=infoblox_network_view.nv1.network_view_name
+ cidr = "10.0.0.0/16"
+ comment = "new network container"
+
+ extensible_attributes = jsonencode({
+ "Tenant ID" = local.tenant_id
+ "Location" = "Test loc."
+ "Site" = "Test site"
+ })
+}
+
+resource "infoblox_ipv4_network" "subnet1"{
+ network_view_name=infoblox_network_view.nv1.network_view_name
+ allocate_prefix_len = 24
+ parent_cidr = infoblox_ipv4_network_container.nc_1.cidr
+ reserve_ip=3
+
+ extensible_attributes = jsonencode({
+ "Tenant ID" = local.tenant_id
+ "Network Name" = "${local.res_prefix}_subnet1"
+ })
+}
+
+resource "infoblox_ipv4_allocation" "alloc1" {
+ network_view_name=infoblox_network_view.nv1.network_view_name
+ cidr=infoblox_ipv4_network.subnet1.cidr
+
+ #Create Host Record with DNS and DHCP flags
+ #dns_view="default"
+ #zone="aws.com"
+ #enable_dns = "false"
+ #enable_dhcp = "false"
+
+ extensible_attributes = jsonencode({
+ "Tenant ID" = local.tenant_id
+ })
+}
+
+resource "infoblox_ipv4_association" "assoc1"{
+ network_view_name=infoblox_network_view.nv1.network_view_name
+ cidr = infoblox_ipv4_allocation.alloc1.cidr
+ mac_addr = local.vm_mac_addr
+ ip_addr = infoblox_ipv4_allocation.alloc1.ip_addr
+
+ #Create Host Record with DNS and DHCP flags
+ #dns_view="default"
+ #zone="aws.com"
+ #enable_dns = "false"
+ #enable_dhcp = "false"
+
+ extensible_attributes = jsonencode({
+ "Tenant ID" = local.tenant_id
+ "VM Name" = "${local.res_prefix}_vm1"
+ "VM ID" = local.vm_id
+ })
+}
+
+resource "infoblox_ipv6_network_container" "nc_2" {
+ network_view_name=infoblox_network_view.nv1.network_view_name
+ cidr = "fc00::/56"
+ comment = "new network container"
+
+ extensible_attributes = jsonencode({
+ "Tenant ID" = local.tenant_id
+ "Location" = "Test loc."
+ "Site" = "Test site"
+ })
+}
+
+resource "infoblox_ipv6_network" "subnet2"{
+ network_view_name=infoblox_network_view.nv1.network_view_name
+ allocate_prefix_len = 64
+ parent_cidr = infoblox_ipv6_network_container.nc_2.cidr
+ reserve_ip=10
+
+
+ extensible_attributes = jsonencode({
+ "Tenant ID" = local.tenant_id
+ "Network Name" = "${local.res_prefix}_subnet2"
+ })
+}
+
+locals {
+ ipv6_reserved_ips = 10
+}
+
+resource "infoblox_ipv6_allocation" "alloc_reserved" {
+ count=local.ipv6_reserved_ips
+
+ network_view_name=infoblox_network_view.nv1.network_view_name
+ cidr=infoblox_ipv6_network.subnet2.cidr
+ duid = format("00:%.2x", count.index)
+
+ #Create Host Record with DNS and DHCP flags
+ #dns_view="default"
+ #zone="aws.com"
+ #enable_dns = "false"
+ #enable_dhcp = "false"
+
+ extensible_attributes = jsonencode({
+ "Tenant ID" = local.tenant_id
+ })
+}
+
+resource "infoblox_ipv6_allocation" "alloc2" {
+ network_view_name=infoblox_network_view.nv1.network_view_name
+ cidr=infoblox_ipv6_network.subnet2.cidr
+ duid = format("00:%.2x", local.ipv6_reserved_ips)
+
+ #Create Host Record with DNS and DHCP flags
+ #dns_view="default"
+ #zone="aws.com"
+ #enable_dns = "false"
+ #enable_dhcp = "false"
+
+ extensible_attributes = jsonencode({
+ "Tenant ID" = local.tenant_id
+ })
+
+ depends_on = [infoblox_ipv6_allocation.alloc_reserved]
+}
+
+resource "infoblox_ipv6_association" "assoc2"{
+ network_view_name=infoblox_network_view.nv1.network_view_name
+ cidr = infoblox_ipv6_allocation.alloc2.cidr
+ mac_addr = local.vm_mac_addr
+ ip_addr = infoblox_ipv6_allocation.alloc2.ip_addr
+ host_name = "test"
+
+ #Create Host Record with DNS and DHCP flags
+ #dns_view="default"
+ #zone="aws.com"
+ #enable_dns = "false"
+ #enable_dhcp = "false"
+
+ extensible_attributes = jsonencode({
+ "Tenant ID" = local.tenant_id
+ "VM Name" = "${local.res_prefix}_vm1"
+ "VM ID" = local.vm_id
+ })
+}
diff --git a/examples/v0.14/Azure/NetworkContainer/IPv6/locals.tf b/examples/v0.14/Azure/NetworkContainer/IPv6/locals.tf
new file mode 120000
index 000000000..1b032e65b
--- /dev/null
+++ b/examples/v0.14/Azure/NetworkContainer/IPv6/locals.tf
@@ -0,0 +1 @@
+../locals.tf
\ No newline at end of file
diff --git a/examples/v0.14/Azure/NetworkContainer/IPv6/terraform.tf b/examples/v0.14/Azure/NetworkContainer/IPv6/terraform.tf
new file mode 120000
index 000000000..fdbf0eba0
--- /dev/null
+++ b/examples/v0.14/Azure/NetworkContainer/IPv6/terraform.tf
@@ -0,0 +1 @@
+../terraform.tf
\ No newline at end of file
diff --git a/examples/v0.14/Azure/NetworkContainer/locals.tf b/examples/v0.14/Azure/NetworkContainer/locals.tf
new file mode 100644
index 000000000..44917699c
--- /dev/null
+++ b/examples/v0.14/Azure/NetworkContainer/locals.tf
@@ -0,0 +1,8 @@
+locals {
+ res_prefix = "terraform_example1"
+ tenant_id = "${local.res_prefix}_tenant"
+
+ # net_view = "default"
+ # ... or (as a non-standard example)
+ net_view = "${local.res_prefix}_netview"
+}
diff --git a/examples/v0.14/Azure/NetworkContainer/terraform.tf b/examples/v0.14/Azure/NetworkContainer/terraform.tf
new file mode 100644
index 000000000..5a64bed52
--- /dev/null
+++ b/examples/v0.14/Azure/NetworkContainer/terraform.tf
@@ -0,0 +1,13 @@
+terraform {
+ # Required providers block for Terraform v0.14
+ required_providers {
+ azurerm = {
+ source = "hashicorp/azurerm"
+ version = "~> 2.50.0"
+ }
+ infoblox = {
+ source = "terraform-providers/infoblox"
+ version = "~> 1.1.0"
+ }
+ }
+}
diff --git a/examples/v0.14/Azure/NextAvailableNetwork/azure.tf b/examples/v0.14/Azure/NextAvailableNetwork/azure.tf
index 158e53f20..0fb8d0356 100644
--- a/examples/v0.14/Azure/NextAvailableNetwork/azure.tf
+++ b/examples/v0.14/Azure/NextAvailableNetwork/azure.tf
@@ -12,7 +12,7 @@ resource "azurerm_virtual_network" "vnet1" {
resource_group_name = azurerm_resource_group.rg1.name
name = "${local.res_prefix}_vnet1"
- address_space = [local.parent_cidr]
+ address_space = [infoblox_ipv4_network_container.v4nc_1.cidr]
}
resource "azurerm_subnet" "net1" {
@@ -20,7 +20,7 @@ resource "azurerm_subnet" "net1" {
virtual_network_name = azurerm_virtual_network.vnet1.name
name = "${local.res_prefix}_net1"
- address_prefixes =[infoblox_network.subnet1.cidr]
+ address_prefixes =[infoblox_ipv4_network.subnet1.cidr]
}
resource "azurerm_subnet" "net2" {
@@ -28,7 +28,7 @@ resource "azurerm_subnet" "net2" {
virtual_network_name = azurerm_virtual_network.vnet1.name
name = "${local.res_prefix}_net2"
- address_prefixes =[infoblox_network.subnet2.cidr]
+ address_prefixes =[infoblox_ipv4_network.subnet2.cidr]
}
resource "azurerm_public_ip" "pub_addr1" {
@@ -49,7 +49,7 @@ resource "azurerm_network_interface" "ni1" {
name = "${local.res_prefix}_ipconfiguration1"
subnet_id = azurerm_subnet.net1.id
private_ip_address_allocation = "Static"
- private_ip_address =infoblox_ip_allocation.alloc1.ip_addr
+ private_ip_address =infoblox_ipv4_allocation.alloc1.ip_addr
public_ip_address_id = azurerm_public_ip.pub_addr1.id
}
@@ -64,7 +64,7 @@ resource "azurerm_network_interface" "ni2" {
name = "${local.res_prefix}_ipconfiguration2"
subnet_id = azurerm_subnet.net2.id
private_ip_address_allocation = "Static"
- private_ip_address =infoblox_ip_allocation.alloc2.ip_addr
+ private_ip_address =infoblox_ipv4_allocation.alloc2.ip_addr
}
}
@@ -72,7 +72,7 @@ resource "azurerm_virtual_machine" "vm1" {
resource_group_name = azurerm_resource_group.rg1.name
location = "ukwest"
- name = infoblox_ip_allocation.alloc1.vm_name
+ name = "${local.res_prefix}_vm1"
network_interface_ids = [azurerm_network_interface.ni1.id, azurerm_network_interface.ni2.id]
primary_network_interface_id = azurerm_network_interface.ni1.id
vm_size = "Standard_A6"
diff --git a/examples/v0.14/Azure/NextAvailableNetwork/infoblox.tf b/examples/v0.14/Azure/NextAvailableNetwork/infoblox.tf
index e7ae6942c..0136a7901 100644
--- a/examples/v0.14/Azure/NextAvailableNetwork/infoblox.tf
+++ b/examples/v0.14/Azure/NextAvailableNetwork/infoblox.tf
@@ -1,35 +1,79 @@
-resource "infoblox_network" "subnet1"{
+resource "infoblox_network_view" "nv1" {
+ tenant_id = local.tenant_id
network_view_name=local.net_view
- tenant_id=local.tenant_id
+}
+
+resource "infoblox_ipv4_network_container" "v4nc_1" {
+ network_view_name=infoblox_network_view.nv1.network_view_name
+ cidr = "10.0.0.0/16"
+ comment = "new network container"
+
+ extensible_attributes = jsonencode({
+ "Location" = "Test loc."
+ "Site" = "Test site"
+ "Tenant ID" = local.tenant_id
+ })
+}
- network_name="${local.res_prefix}_subnet1"
+resource "infoblox_ipv4_network" "subnet1"{
+ network_view_name=infoblox_network_view.nv1.network_view_name
allocate_prefix_len = 24
- parent_cidr = local.parent_cidr
+ parent_cidr = infoblox_ipv4_network_container.v4nc_1.cidr
reserve_ip=3
-}
-resource "infoblox_network" "subnet2"{
- network_view_name=local.net_view
- tenant_id=local.tenant_id
+ extensible_attributes = jsonencode({
+ "Tenant ID" = local.tenant_id
+ "Network Name" = "${local.res_prefix}_subnet1"
+ "TestEA1" = "text3"
+ "TestEA2" = 7
+ })
+}
- network_name="${local.res_prefix}_subnet2"
+resource "infoblox_ipv4_network" "subnet2"{
+ network_view_name=infoblox_network_view.nv1.network_view_name
allocate_prefix_len = 24
- parent_cidr = local.parent_cidr
+ parent_cidr = infoblox_ipv4_network_container.v4nc_1.cidr
reserve_ip=3
+
+ extensible_attributes = jsonencode({
+ "Tenant ID" = local.tenant_id
+ "Network Name" = "${local.res_prefix}_subnet2"
+ Location = "Test loc."
+ Site = "Test site"
+ TestEA1 = ["text1","text2"]
+ TestEA2 = [4,5]
+ })
}
-resource "infoblox_ip_allocation" "alloc1" {
- network_view_name=local.net_view
- tenant_id=local.tenant_id
+resource "infoblox_ipv4_allocation" "alloc1" {
+ network_view_name=infoblox_network_view.nv1.network_view_name
+ cidr=infoblox_ipv4_network.subnet1.cidr
- vm_name="${local.res_prefix}_vm1"
- cidr=infoblox_network.subnet1.cidr
+ #Create Host Record with DNS and DHCP flags
+ #dns_view="default"
+ #zone="aws.com"
+ #enable_dns = "false"
+ #enable_dhcp = "false"
+
+ extensible_attributes = jsonencode({
+ "Tenant ID" = local.tenant_id
+ "VM Name" = "${local.res_prefix}_vm1"
+ })
}
-resource "infoblox_ip_allocation" "alloc2" {
- network_view_name=local.net_view
- tenant_id=local.tenant_id
+resource "infoblox_ipv4_allocation" "alloc2" {
+ network_view_name=infoblox_network_view.nv1.network_view_name
+ cidr=infoblox_ipv4_network.subnet2.cidr
+ host_name = "test"
+
+ #Create Host Record with DNS and DHCP flags
+ #dns_view="default"
+ #zone="aws.com"
+ #enable_dns = "false"
+ #enable_dhcp = "false"
- vm_name="${local.res_prefix}_vm1"
- cidr=infoblox_network.subnet2.cidr
+ extensible_attributes = jsonencode({
+ "Tenant ID" = local.tenant_id
+ "VM Name" = "${local.res_prefix}_vm1"
+ })
}
diff --git a/examples/v0.14/Azure/NextAvailableNetwork/locals.tf b/examples/v0.14/Azure/NextAvailableNetwork/locals.tf
index 21e79aab5..44917699c 100644
--- a/examples/v0.14/Azure/NextAvailableNetwork/locals.tf
+++ b/examples/v0.14/Azure/NextAvailableNetwork/locals.tf
@@ -5,9 +5,4 @@ locals {
# net_view = "default"
# ... or (as a non-standard example)
net_view = "${local.res_prefix}_netview"
- # This network view must exist in the Grid.
-
- # This CIDR must belong to an existing network *container*
- # in the network view specified above.
- parent_cidr = "10.0.0.0/16"
}
diff --git a/examples/v0.14/README.md b/examples/v0.14/README.md
new file mode 100644
index 000000000..782a3ed94
--- /dev/null
+++ b/examples/v0.14/README.md
@@ -0,0 +1,3 @@
+# While using IPv6 Features make sure to consider the following
+* IPv6 Allocation and Association through Fixed Address/Host Record mandates unique DUID in .tf file.
+* For all the cloud providers(AWS, Azure and VMWare), DUID will be updated with MAC address of the interface in NIOS.
diff --git a/examples/v0.14/VMWare/AllocationAndAssociation/infoblox.tf b/examples/v0.14/VMWare/AllocationAndAssociation/infoblox.tf
new file mode 100644
index 000000000..4cacad88e
--- /dev/null
+++ b/examples/v0.14/VMWare/AllocationAndAssociation/infoblox.tf
@@ -0,0 +1,150 @@
+# Create a network container in Infoblox Grid
+resource "infoblox_ipv4_network_container" "IPv4_nw_c" {
+ network_view_name="default"
+
+ cidr = "10.0.0.0/16"
+ comment = "tf IPv4 network container"
+ extensible_attributes = jsonencode({
+ "Tenant ID" = "tf-plugin"
+ Location = "Test loc."
+ Site = "Test site"
+ })
+}
+
+resource "infoblox_ipv6_network_container" "IPv6_nw_c" {
+ network_view_name="default"
+
+ cidr = "2001:1890:1959:2710::/62"
+ comment = "tf IPv6 network container"
+ extensible_attributes = jsonencode({
+ "Tenant ID" = "tf-plugin"
+ Location = "Test loc."
+ Site = "Test site"
+ })
+}
+
+# Allocate a network in Infoblox Grid under provided parent CIDR
+resource "infoblox_ipv4_network" "ipv4_network"{
+ network_view_name = "default"
+
+ parent_cidr = infoblox_ipv4_network_container.IPv4_nw_c.cidr
+ allocate_prefix_len = 24
+ reserve_ip = 2
+
+ comment = "tf IPv4 network"
+ extensible_attributes = jsonencode({
+ "Tenant ID" = "tf-plugin"
+ "Network Name" = "ipv4-tf-network"
+ Location = "Test loc."
+ Site = "Test site"
+ })
+}
+
+resource "infoblox_ipv6_network" "ipv6_network"{
+ network_view_name = "default"
+
+ parent_cidr = infoblox_ipv6_network_container.IPv6_nw_c.cidr
+ allocate_prefix_len = 64
+ reserve_ipv6 = 3
+
+ comment = "tf IPv6 network"
+ extensible_attributes = jsonencode({
+ "Tenant ID" = "tf-plugin"
+ "Network Name" = "ipv6-tf-network"
+ Location = "Test loc."
+ Site = "Test site"
+ })
+}
+
+# Allocate IP from network
+resource "infoblox_ipv4_allocation" "ipv4_allocation"{
+ network_view_name= "default"
+ cidr = infoblox_ipv4_network.ipv4_network.cidr
+ host_name = "test"
+
+ #Create Host Record with DNS and DHCP flags
+ #dns_view="default"
+ #zone="aws.com"
+ #enable_dns = "false"
+ #enable_dhcp = "false"
+
+ comment = "tf IPv4 allocation"
+ extensible_attributes = jsonencode({
+ "Tenant ID" = "tf-plugin"
+ "Network Name" = "ipv4-tf-network"
+ "VM Name" = "tf-vmware-ipv4"
+ Location = "Test loc."
+ Site = "Test site"
+ })
+}
+
+resource "infoblox_ipv6_allocation" "ipv6_allocation" {
+ network_view_name= "default"
+ cidr = infoblox_ipv6_network.ipv6_network.cidr
+ duid = "00:00:00:00:00:00:00:00"
+ host_name = "test"
+
+ #Create Host Record with DNS and DHCP flags
+ #dns_view="default"
+ #zone="aws.com"
+ #enable_dns = "false"
+ #enable_dhcp = "false"
+
+ comment = "tf IPv6 allocation"
+ extensible_attributes = jsonencode({
+ "Tenant ID" = "tf-plugin"
+ "Network Name" = "ipv6-tf-network"
+ "VM Name" = "tf-vmware-ipv6"
+ Location = "Test loc."
+ Site = "Test site"
+ })
+}
+
+# Update Grid with VM data
+resource "infoblox_ipv4_association" "ipv4_associate"{
+ network_view_name = "default"
+ cidr = infoblox_ipv4_network.ipv4_network.cidr
+ ip_addr = infoblox_ipv4_allocation.ipv4_allocation.ip_addr
+ mac_addr = vsphere_virtual_machine.vm_ipv4.network_interface[0].mac_address
+ host_name = "test"
+
+ #Create Host Record with DNS and DHCP flags
+ #dns_view="default"
+ #zone="aws.com"
+ #enable_dns = "false"
+ #enable_dhcp = "false"
+
+ comment = "tf IPv4 Association"
+ extensible_attributes = jsonencode({
+ "Tenant ID" = "tf-plugin"
+ "Network Name" = "ipv6-tf-network"
+ "VM Name" = vsphere_virtual_machine.vm_ipv4.name
+ "VM ID" = vsphere_virtual_machine.vm_ipv4.id
+ Location = "Test loc."
+ Site = "Test site"
+ })
+}
+
+resource "infoblox_ipv6_association" "ipv6_associate"{
+ network_view_name = "default"
+ cidr = infoblox_ipv6_network.ipv6_network.cidr
+ ip_addr = infoblox_ipv6_allocation.ipv6_allocation.ip_addr
+ duid = vsphere_virtual_machine.vm_ipv6.network_interface[0].mac_address
+ host_name = "test"
+
+ #Create Host Record with DNS and DHCP flags
+ #dns_view="default"
+ #zone="aws.com"
+ #enable_dns = "false"
+ #enable_dhcp = "false"
+
+ comment = "tf IPv6 Association"
+ extensible_attributes = jsonencode({
+ "Tenant ID" = "tf-plugin"
+ "Network Name" = "ipv6-tf-network"
+ "VM Name" = vsphere_virtual_machine.vm_ipv6.name
+ "VM ID" = vsphere_virtual_machine.vm_ipv6.id
+ Location = "Test loc."
+ Site = "Test site"
+ })
+}
diff --git a/examples/v0.14/VMWare/AllocationAndAssociation/versions.tf b/examples/v0.14/VMWare/AllocationAndAssociation/versions.tf
new file mode 100644
index 000000000..0a7dd1c3b
--- /dev/null
+++ b/examples/v0.14/VMWare/AllocationAndAssociation/versions.tf
@@ -0,0 +1,12 @@
+terraform {
+ required_providers {
+ infoblox = {
+ source = "terraform-providers/infoblox"
+ version = ">= 1.0"
+ }
+ vsphere = {
+ source = "hashicorp/vsphere"
+ version = "1.12.0"
+ }
+ }
+}
diff --git a/examples/v0.14/VMWare/AllocationAndAssociation/vm.tf b/examples/v0.14/VMWare/AllocationAndAssociation/vm.tf
new file mode 100644
index 000000000..7505efe3f
--- /dev/null
+++ b/examples/v0.14/VMWare/AllocationAndAssociation/vm.tf
@@ -0,0 +1,111 @@
+provider "vsphere" {
+ allow_unverified_ssl = true
+}
+
+data "vsphere_datacenter" "dc"{
+ name = "Blr-Devlab"
+}
+
+data "vsphere_datastore" "datastore" {
+ name = "datastore_44"
+ datacenter_id = data.vsphere_datacenter.dc.id
+}
+
+data "vsphere_resource_pool" "pool" {
+ name = "Blr-Cloud/Resources"
+ datacenter_id = data.vsphere_datacenter.dc.id
+
+}
+
+data "vsphere_network" "network" {
+ name = "VM Network"
+ datacenter_id = data.vsphere_datacenter.dc.id
+}
+
+data "vsphere_virtual_machine" "template" {
+ name = "WebTinyCentOS65x86-tcpdump"
+ datacenter_id = data.vsphere_datacenter.dc.id
+}
+
+# Create VM in vsphere
+resource "vsphere_virtual_machine" "vm_ipv4" {
+ name = lookup(jsondecode(infoblox_ipv4_allocation.ipv4_allocation.extensible_attributes), "VM Name")
+ resource_pool_id = data.vsphere_resource_pool.pool.id
+ datastore_id = data.vsphere_datastore.datastore.id
+ num_cpus = 2
+ memory = 1024
+ guest_id = data.vsphere_virtual_machine.template.guest_id
+ scsi_type = data.vsphere_virtual_machine.template.scsi_type
+
+ network_interface {
+ network_id = data.vsphere_network.network.id
+ adapter_type = data.vsphere_virtual_machine.template.network_interface_types[0]
+ }
+
+ disk {
+ label = "disk0"
+ size = data.vsphere_virtual_machine.template.disks.0.size
+ eagerly_scrub = data.vsphere_virtual_machine.template.disks.0.eagerly_scrub
+ thin_provisioned = data.vsphere_virtual_machine.template.disks.0.thin_provisioned
+ }
+
+ clone {
+ template_uuid = data.vsphere_virtual_machine.template.id
+
+ customize {
+ linux_options {
+ host_name = "terraform-test1"
+ domain = "test.internal"
+ }
+
+ network_interface {
+ ipv4_address = infoblox_ipv4_allocation.ipv4_allocation.ip_addr
+ ipv4_netmask = 24
+ }
+
+ ipv4_gateway = infoblox_ipv4_network.ipv4_network.gateway
+ }
+ }
+}
+
+resource "vsphere_virtual_machine" "vm_ipv6" {
+ name = lookup(jsondecode(infoblox_ipv6_allocation.ipv6_allocation.extensible_attributes), "VM Name")
+ resource_pool_id = data.vsphere_resource_pool.pool.id
+ datastore_id = data.vsphere_datastore.datastore.id
+ wait_for_guest_net_timeout = 0
+ #wait_for_guest_ip_timeout = 5
+ num_cpus = 2
+ memory = 1024
+ guest_id = data.vsphere_virtual_machine.template.guest_id
+ scsi_type = data.vsphere_virtual_machine.template.scsi_type
+
+ network_interface {
+ network_id = data.vsphere_network.network.id
+ adapter_type = data.vsphere_virtual_machine.template.network_interface_types[0]
+ }
+
+ disk {
+ label = "disk0"
+ size = data.vsphere_virtual_machine.template.disks.0.size
+ eagerly_scrub = data.vsphere_virtual_machine.template.disks.0.eagerly_scrub
+ thin_provisioned = data.vsphere_virtual_machine.template.disks.0.thin_provisioned
+ }
+
+ clone {
+ template_uuid = data.vsphere_virtual_machine.template.id
+
+ customize {
+ linux_options {
+ host_name = "terraform-test1"
+ domain = "test.internal"
+ }
+
+ network_interface {
+ ipv6_address = infoblox_ipv6_allocation.ipv6_allocation.ip_addr
+ ipv6_netmask = 64
+ }
+
+ ipv6_gateway = infoblox_ipv6_network.ipv6_network.gateway
+ }
+ }
+}
diff --git a/examples/v0.14/VMWare/Network/IPv4/infoblox.tf b/examples/v0.14/VMWare/Network/IPv4/infoblox.tf
new file mode 100644
index 000000000..adfe1f4d7
--- /dev/null
+++ b/examples/v0.14/VMWare/Network/IPv4/infoblox.tf
@@ -0,0 +1,17 @@
+# Create a network in Infoblox Griby passing the CIDR
+resource "infoblox_ipv4_network" "ipv4_network"{
+ network_view_name = "default"
+
+ parent_cidr = infoblox_ipv4_network_container.IPv4_nw_c.cidr
+ allocate_prefix_len = 24
+ reserve_ip = 2
+
+ comment = "tf IPv4 network"
+ extensible_attributes = jsonencode({
+ "Tenant ID" = "tf-plugin"
+ "Network Name" = "ipv4-tf-network"
+ Location = "Test loc."
+ Site = "Test site"
+ })
+}
+
diff --git a/examples/v0.14/VMWare/Network/IPv4/versions.tf b/examples/v0.14/VMWare/Network/IPv4/versions.tf
new file mode 100644
index 000000000..0a7dd1c3b
--- /dev/null
+++ b/examples/v0.14/VMWare/Network/IPv4/versions.tf
@@ -0,0 +1,12 @@
+terraform {
+ required_providers {
+ infoblox = {
+ source = "terraform-providers/infoblox"
+ version = ">= 1.0"
+ }
+ vsphere = {
+ source = "hashicorp/vsphere"
+ version = "1.12.0"
+ }
+ }
+}
diff --git a/examples/v0.14/VMWare/Network/IPv4/vm.tf b/examples/v0.14/VMWare/Network/IPv4/vm.tf
new file mode 100644
index 000000000..f04d7b193
--- /dev/null
+++ b/examples/v0.14/VMWare/Network/IPv4/vm.tf
@@ -0,0 +1,23 @@
+provider "vsphere" {
+ allow_unverified_ssl = true
+}
+
+data"vsphere_datacenter" "dc"{
+ name = "vRA-DC"
+}
+
+data "vsphere_datastore" "datastore" {
+ name = "datastore_44"
+ datacenter_id = data.vsphere_datacenter.dc.id
+}
+
+data "vsphere_resource_pool" "pool" {
+ name = "Blr-Cloud/Resources"
+ datacenter_id = data.vsphere_datacenter.dc.id
+
+}
+
+data "vsphere_network" "network" {
+ name = "VM Network"
+ datacenter_id = data.vsphere_datacenter.dc.id
+}
diff --git a/examples/v0.14/VMWare/Network/IPv6/infoblox.tf b/examples/v0.14/VMWare/Network/IPv6/infoblox.tf
new file mode 100644
index 000000000..0ef0dfbcb
--- /dev/null
+++ b/examples/v0.14/VMWare/Network/IPv6/infoblox.tf
@@ -0,0 +1,16 @@
+# Create an IPv6 Network in Infoblox Grid when CIDR is passed
+resource "infoblox_ipv6_network" "ipv6_network"{
+ network_view_name = "default"
+
+ parent_cidr = infoblox_ipv6_network_container.IPv6_nw_c.cidr
+ allocate_prefix_len = 64
+ reserve_ipv6 = 3
+
+ comment = "tf IPv6 network"
+ extensible_attributes = jsonencode({
+ "Tenant ID" = "tf-plugin"
+ "Network Name" = "ipv6-tf-network"
+ Location = "Test loc."
+ Site = "Test site"
+ })
+}
diff --git a/examples/v0.14/VMWare/Network/IPv6/versions.tf b/examples/v0.14/VMWare/Network/IPv6/versions.tf
new file mode 100644
index 000000000..0a7dd1c3b
--- /dev/null
+++ b/examples/v0.14/VMWare/Network/IPv6/versions.tf
@@ -0,0 +1,12 @@
+terraform {
+ required_providers {
+ infoblox = {
+ source = "terraform-providers/infoblox"
+ version = ">= 1.0"
+ }
+ vsphere = {
+ source = "hashicorp/vsphere"
+ version = "1.12.0"
+ }
+ }
+}
diff --git a/examples/v0.14/VMWare/Network/IPv6/vm.tf b/examples/v0.14/VMWare/Network/IPv6/vm.tf
new file mode 100644
index 000000000..f04d7b193
--- /dev/null
+++ b/examples/v0.14/VMWare/Network/IPv6/vm.tf
@@ -0,0 +1,23 @@
+provider "vsphere" {
+ allow_unverified_ssl = true
+}
+
+data"vsphere_datacenter" "dc"{
+ name = "vRA-DC"
+}
+
+data "vsphere_datastore" "datastore" {
+ name = "datastore_44"
+ datacenter_id = data.vsphere_datacenter.dc.id
+}
+
+data "vsphere_resource_pool" "pool" {
+ name = "Blr-Cloud/Resources"
+ datacenter_id = data.vsphere_datacenter.dc.id
+
+}
+
+data "vsphere_network" "network" {
+ name = "VM Network"
+ datacenter_id = data.vsphere_datacenter.dc.id
+}
diff --git a/examples/v0.14/VMWare/NetworkContainer/IPv4/infoblox.tf b/examples/v0.14/VMWare/NetworkContainer/IPv4/infoblox.tf
new file mode 100644
index 000000000..bbb5e1642
--- /dev/null
+++ b/examples/v0.14/VMWare/NetworkContainer/IPv4/infoblox.tf
@@ -0,0 +1,13 @@
+# Create an IPv4 network container in Infoblox Grid
+resource "infoblox_ipv4_network_container" "IPv4_nw_c" {
+ network_view_name="default"
+
+ cidr = "10.0.0.0/16"
+ comment = "tf IPv4 network container"
+ extensible_attributes = jsonencode({
+ "Tenant ID" = "tf-plugin"
+ Location = "Test loc."
+ Site = "Test site"
+ })
+}
+
diff --git a/examples/v0.14/VMWare/NetworkContainer/IPv4/versions.tf b/examples/v0.14/VMWare/NetworkContainer/IPv4/versions.tf
new file mode 100644
index 000000000..0a7dd1c3b
--- /dev/null
+++ b/examples/v0.14/VMWare/NetworkContainer/IPv4/versions.tf
@@ -0,0 +1,12 @@
+terraform {
+ required_providers {
+ infoblox = {
+ source = "terraform-providers/infoblox"
+ version = ">= 1.0"
+ }
+ vsphere = {
+ source = "hashicorp/vsphere"
+ version = "1.12.0"
+ }
+ }
+}
diff --git a/examples/v0.14/VMWare/NetworkContainer/IPv4/vm.tf b/examples/v0.14/VMWare/NetworkContainer/IPv4/vm.tf
new file mode 100644
index 000000000..f04d7b193
--- /dev/null
+++ b/examples/v0.14/VMWare/NetworkContainer/IPv4/vm.tf
@@ -0,0 +1,23 @@
+provider "vsphere" {
+ allow_unverified_ssl = true
+}
+
+data"vsphere_datacenter" "dc"{
+ name = "vRA-DC"
+}
+
+data "vsphere_datastore" "datastore" {
+ name = "datastore_44"
+ datacenter_id = data.vsphere_datacenter.dc.id
+}
+
+data "vsphere_resource_pool" "pool" {
+ name = "Blr-Cloud/Resources"
+ datacenter_id = data.vsphere_datacenter.dc.id
+
+}
+
+data "vsphere_network" "network" {
+ name = "VM Network"
+ datacenter_id = data.vsphere_datacenter.dc.id
+}
diff --git a/examples/v0.14/VMWare/NetworkContainer/IPv6/infoblox.tf b/examples/v0.14/VMWare/NetworkContainer/IPv6/infoblox.tf
new file mode 100644
index 000000000..d5deadadd
--- /dev/null
+++ b/examples/v0.14/VMWare/NetworkContainer/IPv6/infoblox.tf
@@ -0,0 +1,57 @@
+# Create a network container in Infoblox Grid
+resource "infoblox_ipv4_network_container" "IPv4_nw_c" {
+ network_view_name="default"
+
+ cidr = "10.0.0.0/16"
+ comment = "tf IPv4 network container"
+ extensible_attributes = jsonencode({
+ "Tenant ID" = "tf-plugin"
+ Location = "Test loc."
+ Site = "Test site"
+ })
+}
+
+resource "infoblox_ipv6_network_container" "IPv6_nw_c" {
+ network_view_name="default"
+
+ cidr = "2001:1890:1959:2710::/62"
+ comment = "tf IPv6 network container"
+ extensible_attributes = jsonencode({
+ "Tenant ID" = "tf-plugin"
+ Location = "Test loc."
+ Site = "Test site"
+ })
+}
+
+# Allocate a network in Infoblox Grid under provided parent CIDR
+resource "infoblox_ipv4_network" "ipv4_network"{
+ network_view_name = "default"
+
+ parent_cidr = infoblox_ipv4_network_container.IPv4_nw_c.cidr
+ allocate_prefix_len = 24
+ reserve_ip = 2
+
+ comment = "tf IPv4 network"
+ extensible_attributes = jsonencode({
+ "Tenant ID" = "tf-plugin"
+ "Network Name" = "ipv4-tf-network"
+ Location = "Test loc."
+ Site = "Test site"
+ })
+}
+
+resource "infoblox_ipv6_network" "ipv6_network"{
+ network_view_name = "default"
+
+ parent_cidr = infoblox_ipv6_network_container.IPv6_nw_c.cidr
+ allocate_prefix_len = 64
+ reserve_ipv6 = 3
+
+ comment = "tf IPv6 network"
+ extensible_attributes = jsonencode({
+ "Tenant ID" = "tf-plugin"
+ "Network Name" = "ipv6-tf-network"
+ Location = "Test loc."
+ Site = "Test site"
+ })
+}
diff --git a/examples/v0.14/VMWare/NetworkContainer/IPv6/versions.tf b/examples/v0.14/VMWare/NetworkContainer/IPv6/versions.tf
new file mode 100644
index 000000000..0a7dd1c3b
--- /dev/null
+++ b/examples/v0.14/VMWare/NetworkContainer/IPv6/versions.tf
@@ -0,0 +1,12 @@
+terraform {
+ required_providers {
+ infoblox = {
+ source = "terraform-providers/infoblox"
+ version = ">= 1.0"
+ }
+ vsphere = {
+ source = "hashicorp/vsphere"
+ version = "1.12.0"
+ }
+ }
+}
diff --git a/examples/v0.14/VMWare/NetworkContainer/IPv6/vm.tf b/examples/v0.14/VMWare/NetworkContainer/IPv6/vm.tf
new file mode 100644
index 000000000..f04d7b193
--- /dev/null
+++ b/examples/v0.14/VMWare/NetworkContainer/IPv6/vm.tf
@@ -0,0 +1,23 @@
+provider "vsphere" {
+ allow_unverified_ssl = true
+}
+
+data"vsphere_datacenter" "dc"{
+ name = "vRA-DC"
+}
+
+data "vsphere_datastore" "datastore" {
+ name = "datastore_44"
+ datacenter_id = data.vsphere_datacenter.dc.id
+}
+
+data "vsphere_resource_pool" "pool" {
+ name = "Blr-Cloud/Resources"
+ datacenter_id = data.vsphere_datacenter.dc.id
+
+}
+
+data "vsphere_network" "network" {
+ name = "VM Network"
+ datacenter_id = data.vsphere_datacenter.dc.id
+}
diff --git a/examples/v0.14/VMWare/NextAvailableNetwork/infoblox.tf b/examples/v0.14/VMWare/NextAvailableNetwork/infoblox.tf
index bee583bdd..d5deadadd 100644
--- a/examples/v0.14/VMWare/NextAvailableNetwork/infoblox.tf
+++ b/examples/v0.14/VMWare/NextAvailableNetwork/infoblox.tf
@@ -1,30 +1,57 @@
+# Create a network container in Infoblox Grid
+resource "infoblox_ipv4_network_container" "IPv4_nw_c" {
+ network_view_name="default"
+
+ cidr = "10.0.0.0/16"
+ comment = "tf IPv4 network container"
+ extensible_attributes = jsonencode({
+ "Tenant ID" = "tf-plugin"
+ Location = "Test loc."
+ Site = "Test site"
+ })
+}
+
+resource "infoblox_ipv6_network_container" "IPv6_nw_c" {
+ network_view_name="default"
+
+ cidr = "2001:1890:1959:2710::/62"
+ comment = "tf IPv6 network container"
+ extensible_attributes = jsonencode({
+ "Tenant ID" = "tf-plugin"
+ Location = "Test loc."
+ Site = "Test site"
+ })
+}
+
# Allocate a network in Infoblox Grid under provided parent CIDR
-resource "infoblox_network" "demo_network"{
+resource "infoblox_ipv4_network" "ipv4_network"{
network_view_name = "default"
- network_name = "test_network"
- tenant_id = "test"
+
+ parent_cidr = infoblox_ipv4_network_container.IPv4_nw_c.cidr
allocate_prefix_len = 24
- parent_cidr = "10.0.0.0/16"
- reserve_ip = 2
-}
+ reserve_ip = 2
-# Allocate IP from network
-resource "infoblox_ip_allocation" "demo_allocation"{
- network_view_name = "default"
- vm_name = "terraform-demo"
- cidr = infoblox_network.demo_network.cidr
- tenant_id = "test"
+ comment = "tf IPv4 network"
+ extensible_attributes = jsonencode({
+ "Tenant ID" = "tf-plugin"
+ "Network Name" = "ipv4-tf-network"
+ Location = "Test loc."
+ Site = "Test site"
+ })
}
-# Update Grid with VM data
-resource "infoblox_ip_association" "demo_associate"{
+resource "infoblox_ipv6_network" "ipv6_network"{
network_view_name = "default"
- vm_name = infoblox_ip_allocation.demo_allocation.vm_name
- cidr = infoblox_network.demo_network.cidr
- mac_addr = vsphere_virtual_machine.vm.network_interface.0.mac_address
- ip_addr = infoblox_ip_allocation.demo_allocation.ip_addr
- vm_id = vsphere_virtual_machine.vm.id
- tenant_id ="test"
-}
+ parent_cidr = infoblox_ipv6_network_container.IPv6_nw_c.cidr
+ allocate_prefix_len = 64
+ reserve_ipv6 = 3
+ comment = "tf IPv6 network"
+ extensible_attributes = jsonencode({
+ "Tenant ID" = "tf-plugin"
+ "Network Name" = "ipv6-tf-network"
+ Location = "Test loc."
+ Site = "Test site"
+ })
+}
diff --git a/examples/v0.14/VMWare/NextAvailableNetwork/vm.tf b/examples/v0.14/VMWare/NextAvailableNetwork/vm.tf
index fbb21ff78..61a9f9f31 100644
--- a/examples/v0.14/VMWare/NextAvailableNetwork/vm.tf
+++ b/examples/v0.14/VMWare/NextAvailableNetwork/vm.tf
@@ -33,6 +33,7 @@ data "vsphere_virtual_machine" "template" {
datacenter_id = data.vsphere_datacenter.dc.id
}
+/*
resource "vsphere_virtual_machine" "vm" {
name = infoblox_ip_allocation.demo_allocation.vm_name
resource_pool_id = data.vsphere_resource_pool.pool.id
@@ -72,4 +73,4 @@ resource "vsphere_virtual_machine" "vm" {
}
}
}
-
+*/
diff --git a/examples/v0.14/VMWare/README.md b/examples/v0.14/VMWare/README.md
index 1e6f9ffc8..96393dc7a 100644
--- a/examples/v0.14/VMWare/README.md
+++ b/examples/v0.14/VMWare/README.md
@@ -13,12 +13,16 @@ export INFOBLOX_USERNAME="${username}"
#Using the templates for different combinations.
+- NetworkContainer : Create IPv4/IPv6 Network Containers
+- Network : Create IPv4/IPv6 Network
- To get next available network from a given parent CIDR of a prefix length use
templates from NextAvailableNetwork.
### Note
```
A parent network container has to be in existence before requesting next available network from it.
+
+There are no datasources to obtain CIDR values from vsphere. Hence, the values have to be entered explicitly in infoblox.tf files.
```
# Running the Resource
diff --git a/infoblox/datasource_infoblox_a_record.go b/infoblox/datasource_infoblox_a_record.go
index 0a2bfbfde..7efe1bd7f 100644
--- a/infoblox/datasource_infoblox_a_record.go
+++ b/infoblox/datasource_infoblox_a_record.go
@@ -66,14 +66,16 @@ func dataSourceARecordRead(d *schema.ResourceData, m interface{}) error {
connector := m.(*ibclient.Connector)
- search_data := ibclient.NewRecordA(
- ibclient.RecordA{
- Ipv4Addr: ip_addr,
- Name: fqdn,
- Zone: zone,
- View: dnsView,
- })
- err := connector.GetObject(search_data, "", &records)
+ aRec := ibclient.NewEmptyRecordA()
+ sf := map[string]string{
+ "ipv4addr": ip_addr,
+ "name": fqdn,
+ "zone": zone,
+ "view": dnsView,
+ }
+ queryParams := ibclient.NewQueryParams(false, sf)
+
+ err := connector.GetObject(aRec, "", queryParams, &records)
d.SetId("")
if err != nil {
return fmt.Errorf("Read A record failed: %s", err)
diff --git a/infoblox/datasource_infoblox_cname_record.go b/infoblox/datasource_infoblox_cname_record.go
index da65e1efe..941ef6bb9 100644
--- a/infoblox/datasource_infoblox_cname_record.go
+++ b/infoblox/datasource_infoblox_cname_record.go
@@ -66,14 +66,15 @@ func dataSourceCNameRecordRead(d *schema.ResourceData, m interface{}) error {
connector := m.(*ibclient.Connector)
- search_data := ibclient.NewRecordCNAME(
- ibclient.RecordCNAME{
- Canonical: canonical,
- Name: fqdn,
- Zone: zone,
- View: dnsView,
- })
- err := connector.GetObject(search_data, "", &records)
+ cnRec := ibclient.NewRecordCNAME(ibclient.RecordCNAME{})
+ sf := map[string]string{
+ "canonical": canonical,
+ "name": fqdn,
+ "zone": zone,
+ "view": dnsView,
+ }
+ queryParams := ibclient.NewQueryParams(false, sf)
+ err := connector.GetObject(cnRec, "", queryParams, &records)
d.SetId("")
if err != nil {
return fmt.Errorf("Read CNAME record failed: %s", err)
diff --git a/infoblox/datasource_infoblox_network.go b/infoblox/datasource_infoblox_network.go
index 4607fbf53..cc38c78f0 100644
--- a/infoblox/datasource_infoblox_network.go
+++ b/infoblox/datasource_infoblox_network.go
@@ -44,7 +44,7 @@ func dataSourceNetworkRead(d *schema.ResourceData, m interface{}) error {
objMgr := ibclient.NewObjectManager(connector, "Terraform", tenantID)
- obj, err := objMgr.GetNetwork(networkViewName, cidr, nil)
+ obj, err := objMgr.GetNetwork(networkViewName, cidr, false, nil)
if err != nil {
return fmt.Errorf("Getting Network block from network (%s) failed : %s", cidr, err)
}
diff --git a/infoblox/provider.go b/infoblox/provider.go
index 541ba599d..1f5e3b423 100644
--- a/infoblox/provider.go
+++ b/infoblox/provider.go
@@ -8,6 +8,8 @@ import (
ibclient "github.com/infobloxopen/infoblox-go-client"
)
+const defaultTenantId = "default_tenant"
+
//Provider returns a terraform.ResourceProvider.
func Provider() terraform.ResourceProvider {
return &schema.Provider{
@@ -63,13 +65,18 @@ func Provider() terraform.ResourceProvider {
},
},
ResourcesMap: map[string]*schema.Resource{
- "infoblox_network": resourceNetwork(),
- "infoblox_network_view": resourceNetworkView(),
- "infoblox_ip_allocation": resourceIPAllocation(),
- "infoblox_ip_association": resourceIPAssociation(),
- "infoblox_a_record": resourceARecord(),
- "infoblox_cname_record": resourceCNAMERecord(),
- "infoblox_ptr_record": resourcePTRRecord(),
+ "infoblox_network_view": resourceNetworkView(),
+ "infoblox_ipv4_network_container": resourceIPv4NetworkContainer(),
+ "infoblox_ipv6_network_container": resourceIPv6NetworkContainer(),
+ "infoblox_ipv4_network": resourceIPv4Network(),
+ "infoblox_ipv6_network": resourceIPv6Network(),
+ "infoblox_ipv4_allocation": resourceIPv4Allocation(),
+ "infoblox_ipv6_allocation": resourceIPv6Allocation(),
+ "infoblox_ipv4_association": resourceIPv4Association(),
+ "infoblox_ipv6_association": resourceIPv6Association(),
+ "infoblox_a_record": resourceARecord(),
+ "infoblox_cname_record": resourceCNAMERecord(),
+ "infoblox_ptr_record": resourcePTRRecord(),
},
DataSourcesMap: map[string]*schema.Resource{
"infoblox_network": dataSourceNetwork(),
diff --git a/infoblox/resource_infoblox_ip_allocation.go b/infoblox/resource_infoblox_ip_allocation.go
index f0b342d6f..e666631a5 100644
--- a/infoblox/resource_infoblox_ip_allocation.go
+++ b/infoblox/resource_infoblox_ip_allocation.go
@@ -1,228 +1,500 @@
package infoblox
import (
+ "encoding/json"
"fmt"
+
"github.com/hashicorp/terraform/helper/schema"
- "github.com/infobloxopen/infoblox-go-client"
- "log"
+ ibclient "github.com/infobloxopen/infoblox-go-client"
)
func resourceIPAllocation() *schema.Resource {
return &schema.Resource{
- Create: resourceIPAllocationRequest,
- Read: resourceIPAllocationGet,
- Update: resourceIPAllocationUpdate,
- Delete: resourceIPAllocationRelease,
-
Schema: map[string]*schema.Schema{
- "network_view_name": &schema.Schema{
+ "network_view_name": {
Type: schema.TypeString,
Optional: true,
Default: "default",
- Description: "Network view name available in Nios server.",
- },
- "vm_name": &schema.Schema{
- Type: schema.TypeString,
- Required: true,
- Description: "The name of the VM.",
- },
- "cidr": &schema.Schema{
- Type: schema.TypeString,
- Required: true,
- Description: "The address in cidr format.",
+ Description: "Network view name of NIOS server.",
},
- "zone": &schema.Schema{
- Type: schema.TypeString,
+ "enable_dns": {
+ Type: schema.TypeBool,
Optional: true,
- Description: "Zone under which host record has to be created.",
+ Default: true,
+ Description: "flag that defines if the host record is to be used for DNS Purposes.",
},
- "enable_dns": &schema.Schema{
+ "enable_dhcp": {
Type: schema.TypeBool,
Optional: true,
Default: false,
- Description: "flag that defines if the host reocrd is used for DNS or IPAM Purposes.",
+ Description: "flag that defines if the host record is to be used for IPAM Purposes.",
},
- "dns_view": &schema.Schema{
+ "dns_view": {
Type: schema.TypeString,
Optional: true,
Description: "Dns View under which the zone has been created.",
},
- "ip_addr": &schema.Schema{
+ "zone": {
+ Type: schema.TypeString,
+ Optional: true,
+ Description: "Zone under which host record has to be created.",
+ },
+ "cidr": {
+ Type: schema.TypeString,
+ Required: true,
+ Description: "The address in cidr format.",
+ },
+ "ip_addr": {
Type: schema.TypeString,
Optional: true,
- Description: "IP address your instance in cloud.For static allocation ,set the field with valid IP. For dynamic allocation, leave this field empty.",
+ Description: "IP address of cloud instance. Set a valid IP for static allocation and leave empty if dynamically allocated.",
Computed: true,
},
- "mac_addr": &schema.Schema{
+ "mac_addr": {
Type: schema.TypeString,
Optional: true,
- Description: "mac address of your instance in cloud.",
+ Description: "MAC Address of cloud instance.",
},
- "vm_id": &schema.Schema{
+ "duid": {
Type: schema.TypeString,
Optional: true,
- Description: "instance id.",
+ Description: "DHCP unique identifier for IPv6.",
},
- "tenant_id": &schema.Schema{
+ "host_name": {
Type: schema.TypeString,
Required: true,
- Description: "Unique identifier of your tenant in cloud.",
+ Description: "The host name",
+ },
+ "comment": {
+ Type: schema.TypeString,
+ Default: "",
+ Optional: true,
+ Description: "A description of the IP allocation.",
+ },
+ "extensible_attributes": {
+ Type: schema.TypeString,
+ Default: "",
+ Optional: true,
+ Description: "The Extensible attributes of the network container to be added/updated, as a map in JSON format",
},
},
}
}
-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))
-
+func resourceIPAllocationRequest(d *schema.ResourceData, m interface{}, isIPv6 bool) error {
networkViewName := d.Get("network_view_name").(string)
- //This is for record Name
- recordName := d.Get("vm_name").(string)
- ipAddr := d.Get("ip_addr").(string)
+ dnsView := d.Get("dns_view").(string)
+ enableDns := d.Get("enable_dns").(bool)
+ enableDhcp := d.Get("enable_dhcp").(bool)
+ zone := d.Get("zone").(string)
+ hostName := d.Get("host_name").(string)
+
cidr := d.Get("cidr").(string)
+ ipAddr := d.Get("ip_addr").(string)
macAddr := d.Get("mac_addr").(string)
- //This is for EA's
- vmName := d.Get("vm_name").(string)
- vmID := d.Get("vm_id").(string)
- tenantID := d.Get("tenant_id").(string)
- zone := d.Get("zone").(string)
- enableDns := d.Get("enable_dns").(bool)
- dnsView := d.Get("dns_view").(string)
+ duid := d.Get("duid").(string)
+
+ comment := d.Get("comment").(string)
+ extAttrJSON := d.Get("extensible_attributes").(string)
+ extAttrs := make(map[string]interface{})
+ if extAttrJSON != "" {
+ if err := json.Unmarshal([]byte(extAttrJSON), &extAttrs); err != nil {
+ return fmt.Errorf("cannot process 'extensible_attributes' field: %s", err.Error())
+ }
+ }
- connector := m.(*ibclient.Connector)
ZeroMacAddr := "00:00:00:00:00:00"
- //fqdn
- name := recordName + "." + zone
- ea := make(ibclient.EA)
- if vmName != "" {
- ea["VM Name"] = vmName
+ connector := m.(*ibclient.Connector)
+
+ var tenantID string
+ for attrName, attrValueInf := range extAttrs {
+ attrValue, _ := attrValueInf.(string)
+ if attrName == "Tenant ID" {
+ tenantID = attrValue
+ }
+ }
+
+ if hostName == "" {
+ return fmt.Errorf("'host_name' is mandatory to be passed for Allocation of IP")
}
- if vmID != "" {
- ea["VM ID"] = vmID
+
+ var recFQDN string
+ if len(zone) > 0 {
+ recFQDN = hostName + "." + zone
+ } else {
+ recFQDN = hostName
}
+
if macAddr == "" {
macAddr = ZeroMacAddr
}
+
objMgr := ibclient.NewObjectManager(connector, "Terraform", tenantID)
- if (zone != "" || len(zone) != 0) && (dnsView != "" || len(dnsView) != 0) {
- hostAddressObj, err := objMgr.CreateHostRecord(enableDns, name, networkViewName, dnsView, cidr, ipAddr, macAddr, ea)
- if err != nil {
- return fmt.Errorf("Error allocating IP from network block(%s): %s", cidr, err)
+ if (zone != "" || len(zone) != 0) && (dnsView != "" || len(dnsView) != 0) && enableDns {
+ if isIPv6 {
+ Obj, err := objMgr.CreateHostRecord(
+ enableDns,
+ enableDhcp,
+ recFQDN,
+ networkViewName,
+ dnsView,
+ "", cidr,
+ "", ipAddr,
+ "", duid,
+ comment,
+ extAttrs, []string{})
+ if err != nil {
+ return fmt.Errorf(
+ "Error in allocating an IPv6 address and creating a host record in cidr %s: %s", cidr, err.Error())
+ }
+ d.Set("ip_addr", Obj.Ipv6Addrs[0].Ipv6Addr)
+ d.SetId(Obj.Ref)
+ } else {
+ Obj, err := objMgr.CreateHostRecord(
+ enableDns,
+ enableDhcp,
+ recFQDN,
+ networkViewName,
+ dnsView,
+ cidr, "",
+ ipAddr, "",
+ macAddr, "",
+ comment,
+ extAttrs, []string{})
+ if err != nil {
+ return fmt.Errorf(
+ "Error in allocating an IPv4 address and creating a host record in cidr %s: %s", cidr, err.Error())
+ }
+ d.Set("ip_addr", Obj.Ipv4Addrs[0].Ipv4Addr)
+ d.SetId(Obj.Ref)
+ }
+
+ } else if enableDhcp || !enableDns {
+ // default value of enableDns is true. When user sets enableDhcp as true and does not pass a enableDns flag
+ enableDns = false
+
+ if isIPv6 {
+ Obj, err := objMgr.CreateHostRecord(
+ enableDns,
+ enableDhcp,
+ recFQDN,
+ networkViewName,
+ dnsView,
+ "", cidr,
+ "", ipAddr,
+ "", duid,
+ comment,
+ extAttrs, []string{})
+ if err != nil {
+ return fmt.Errorf(
+ "Error in allocating an IPv6 address and creating a host record in cidr %s: %s", cidr, err.Error())
+ }
+ d.Set("ip_addr", Obj.Ipv6Addrs[0].Ipv6Addr)
+ d.SetId(Obj.Ref)
+ } else {
+ Obj, err := objMgr.CreateHostRecord(
+ enableDns,
+ enableDhcp,
+ recFQDN,
+ networkViewName,
+ dnsView,
+ cidr, "",
+ ipAddr, "",
+ macAddr, "",
+ comment,
+ extAttrs, []string{})
+ if err != nil {
+ return fmt.Errorf(
+ "Error in allocating an IPv4 address and creating a host record in cidr %s: %s", cidr, err.Error())
+ }
+ d.Set("ip_addr", Obj.Ipv4Addrs[0].Ipv4Addr)
+ d.SetId(Obj.Ref)
}
- d.Set("ip_addr", hostAddressObj.Ipv4Addrs[0].Ipv4Addr)
- d.SetId(hostAddressObj.Ref)
+
} else {
- fixedAddressObj, err := objMgr.AllocateIP(networkViewName, cidr, ipAddr, macAddr, recordName, ea)
- if err != nil {
- return fmt.Errorf("Error allocating IP from network block(%s): %s", cidr, err)
+ if isIPv6 {
+ Obj, err := objMgr.AllocateIP(networkViewName, cidr, ipAddr, isIPv6, duid, hostName, comment, extAttrs)
+ if err != nil {
+ return fmt.Errorf("Error allocating IP from network block %s: %s", cidr, err.Error())
+ }
+ d.Set("ip_addr", Obj.IPv6Address)
+ d.SetId(Obj.Ref)
+ } else {
+ Obj, err := objMgr.AllocateIP(networkViewName, cidr, ipAddr, isIPv6, macAddr, hostName, comment, extAttrs)
+ if err != nil {
+ return fmt.Errorf("Error allocating IP from network block %s: %s", cidr, err.Error())
+ }
+ d.Set("ip_addr", Obj.IPv4Address)
+ d.SetId(Obj.Ref)
}
- d.Set("ip_addr", fixedAddressObj.IPAddress)
- d.SetId(fixedAddressObj.Ref)
}
- log.Printf("[DEBUG] %s:completing Request of IP from required network block", resourceIPAllocationIDString(d))
- return resourceIPAllocationGet(d, m)
+ return nil
}
-func resourceIPAllocationGet(d *schema.ResourceData, m interface{}) error {
-
- log.Printf("[DEBUG] %s:Reading the required IP from network block", resourceIPAllocationIDString(d))
+func resourceIPAllocationGet(d *schema.ResourceData, m interface{}, isIPv6 bool) error {
- tenantID := d.Get("tenant_id").(string)
- cidr := d.Get("cidr").(string)
- zone := d.Get("zone").(string)
dnsView := d.Get("dns_view").(string)
- connector := m.(*ibclient.Connector)
+ zone := d.Get("zone").(string)
+ cidr := d.Get("cidr").(string)
+ extAttrJSON := d.Get("extensible_attributes").(string)
+ extAttrs := make(map[string]interface{})
+ if extAttrJSON != "" {
+ if err := json.Unmarshal([]byte(extAttrJSON), &extAttrs); err != nil {
+ return fmt.Errorf("cannot process 'extensible_attributes' field: %s", err.Error())
+ }
+ }
+ var tenantID string
+ for attrName, attrValueInf := range extAttrs {
+ attrValue, _ := attrValueInf.(string)
+ if attrName == "Tenant ID" {
+ tenantID = attrValue
+ break
+ }
+ }
+
+ connector := m.(*ibclient.Connector)
objMgr := ibclient.NewObjectManager(connector, "Terraform", tenantID)
if (zone != "" || len(zone) != 0) && (dnsView != "" || len(dnsView) != 0) {
obj, err := objMgr.GetHostRecordByRef(d.Id())
if err != nil {
- return fmt.Errorf("Error getting IP from network block(%s): %s", cidr, err)
+ return fmt.Errorf("Error getting IP from network block %s: %s", cidr, err.Error())
}
d.SetId(obj.Ref)
} else {
obj, err := objMgr.GetFixedAddressByRef(d.Id())
if err != nil {
- return fmt.Errorf("Error getting IP from network block(%s): %s", cidr, err)
+ return fmt.Errorf("Error getting IP from network block %s: %s", cidr, err.Error())
}
d.SetId(obj.Ref)
}
- log.Printf("[DEBUG] %s: Completed Reading IP from the network block", resourceIPAllocationIDString(d))
return nil
}
-func resourceIPAllocationUpdate(d *schema.ResourceData, m interface{}) error {
+func resourceIPAllocationUpdate(d *schema.ResourceData, m interface{}, isIPv6 bool) error {
- match_client := "MAC_ADDRESS"
-
- log.Printf("[DEBUG] %s: Updating the Parameters of the allocated IP in the specified network block", resourceIPAllocationIDString(d))
+ enableDns := d.Get("enable_dns").(bool)
+ enableDhcp := d.Get("enable_dhcp").(bool)
+ dnsView := d.Get("dns_view").(string)
+ zone := d.Get("zone").(string)
+ hostName := d.Get("host_name").(string)
+ duid := d.Get("duid").(string)
macAddr := d.Get("mac_addr").(string)
- tenantID := d.Get("tenant_id").(string)
- vmID := d.Get("vm_id").(string)
- vmName := d.Get("vm_name").(string)
- zone := d.Get("zone").(string)
- dnsView := d.Get("dns_view").(string)
- connector := m.(*ibclient.Connector)
+ comment := d.Get("comment").(string)
+ extAttrJSON := d.Get("extensible_attributes").(string)
+ extAttrs := make(map[string]interface{})
+ if extAttrJSON != "" {
+ if err := json.Unmarshal([]byte(extAttrJSON), &extAttrs); err != nil {
+ return fmt.Errorf("cannot process 'extensible_attributes' field: %s", err.Error())
+ }
+ }
+ var tenantID string
+ for attrName, attrValueInf := range extAttrs {
+ attrValue, _ := attrValueInf.(string)
+ if attrName == "Tenant ID" {
+ tenantID = attrValue
+ }
+ }
+
+ if hostName == "" {
+ return fmt.Errorf("'hostName' is mandatory to be passed for Allocation of IP")
+ }
+
+ var recFQDN string
+ if len(zone) > 0 {
+ recFQDN = hostName + "." + zone
+ } else {
+ recFQDN = hostName
+ }
+
+ connector := m.(*ibclient.Connector)
objMgr := ibclient.NewObjectManager(connector, "Terraform", tenantID)
- if (zone != "" || len(zone) != 0) && (dnsView != "" || len(dnsView) != 0) {
+ if (zone != "" || len(zone) != 0) && (dnsView != "" || len(dnsView) != 0) && enableDns {
hostRecordObj, _ := objMgr.GetHostRecordByRef(d.Id())
- IPAddrObj, _ := objMgr.GetIpAddressFromHostRecord(*hostRecordObj)
- obj, err := objMgr.UpdateHostRecord(d.Id(), IPAddrObj, macAddr, vmID, vmName)
- if err != nil {
- return fmt.Errorf("Error updating IP from network block having reference (%s): %s", d.Id(), err)
+
+ if isIPv6 {
+ IPAddrObj := hostRecordObj.Ipv6Addr
+ obj, err := objMgr.UpdateHostRecord(
+ d.Id(),
+ enableDns,
+ enableDhcp,
+ recFQDN,
+ "", IPAddrObj,
+ "", duid,
+ comment,
+ extAttrs, []string{})
+ if err != nil {
+ return fmt.Errorf(
+ "Error updating Host record of IPv6 from network block having reference %s: %s", d.Id(), err.Error())
+ }
+ d.SetId(obj.Ref)
+ } else {
+ IPAddrObj := hostRecordObj.Ipv4Addr
+ obj, err := objMgr.UpdateHostRecord(
+ d.Id(),
+ enableDns,
+ enableDhcp,
+ recFQDN,
+ IPAddrObj, "",
+ macAddr, "",
+ comment,
+ extAttrs, []string{})
+ if err != nil {
+ return fmt.Errorf(
+ "Error updating Host record of IPv4 from network block having reference %s: %s", d.Id(), err.Error())
+ }
+ d.SetId(obj.Ref)
+ }
+ } else if enableDhcp || !enableDns {
+ hostRecordObj, _ := objMgr.GetHostRecordByRef(d.Id())
+
+ // default value of enableDns is true. When user sets enableDhcp as true and does not pass a enableDns flag
+ enableDns = false
+
+ if isIPv6 {
+ IPAddrObj := hostRecordObj.Ipv6Addr
+ obj, err := objMgr.UpdateHostRecord(
+ d.Id(),
+ enableDns,
+ enableDhcp,
+ recFQDN,
+ "", IPAddrObj,
+ "", duid,
+ comment,
+ extAttrs, []string{})
+ if err != nil {
+ return fmt.Errorf(
+ "Error updating Host record of IPv6 from network block having reference %s: %s", d.Id(), err.Error())
+ }
+ d.SetId(obj.Ref)
+ } else {
+ IPAddrObj := hostRecordObj.Ipv4Addr
+ obj, err := objMgr.UpdateHostRecord(
+ d.Id(),
+ enableDns,
+ enableDhcp,
+ recFQDN,
+ IPAddrObj, "",
+ macAddr, "",
+ comment,
+ extAttrs, []string{})
+ if err != nil {
+ return fmt.Errorf(
+ "Error updating Host record of IPv4 from network block having reference %s: %s", d.Id(), err.Error())
+ }
+ d.SetId(obj.Ref)
}
- d.SetId(obj)
} else {
- obj, err := objMgr.UpdateFixedAddress(d.Id(), match_client, macAddr, vmID, vmName)
+ var macOrDuid string
+ match_client := "MAC_ADDRESS"
+ if isIPv6 {
+ macOrDuid = duid
+ match_client = ""
+ } else {
+ macOrDuid = macAddr
+ }
+ obj, err := objMgr.UpdateFixedAddress(d.Id(), hostName, match_client, macOrDuid, comment, extAttrs)
if err != nil {
- return fmt.Errorf("Error updating IP from network block having reference (%s): %s", d.Id(), err)
+ return fmt.Errorf("Error updating IP from network block having reference %s: %s", d.Id(), err.Error())
}
d.SetId(obj.Ref)
}
- log.Printf("[DEBUG] %s: Updation of Parameters of allocated IP complete in the specified network block", resourceIPAllocationIDString(d))
- return resourceIPAllocationGet(d, m)
+ return nil
}
-func resourceIPAllocationRelease(d *schema.ResourceData, m interface{}) error {
+func resourceIPAllocationRelease(d *schema.ResourceData, m interface{}, isIPv6 bool) error {
- log.Printf("[DEBUG] %s: Beginning Release of an allocated IP in the specified network block", resourceIPAllocationIDString(d))
-
- tenantID := d.Get("tenant_id").(string)
- zone := d.Get("zone").(string)
dnsView := d.Get("dns_view").(string)
- connector := m.(*ibclient.Connector)
+ zone := d.Get("zone").(string)
+ extAttrJSON := d.Get("extensible_attributes").(string)
+ extAttrs := make(map[string]interface{})
+ if extAttrJSON != "" {
+ if err := json.Unmarshal([]byte(extAttrJSON), &extAttrs); err != nil {
+ return fmt.Errorf("cannot process 'extensible_attributes' field: %s", err.Error())
+ }
+ }
+ var tenantID string
+ for attrName, attrValue := range extAttrs {
+ if attrName == "Tenant ID" {
+ tenantID = attrValue.(string)
+ break
+ }
+ }
+ connector := m.(*ibclient.Connector)
objMgr := ibclient.NewObjectManager(connector, "Terraform", tenantID)
+
if (zone != "" || len(zone) != 0) && (dnsView != "" || len(dnsView) != 0) {
_, err := objMgr.DeleteHostRecord(d.Id())
if err != nil {
- return fmt.Errorf("Error Releasing IP from network block having reference (%s): %s", d.Id(), err)
+ return fmt.Errorf("Error Releasing IP from network block having reference %s: %s", d.Id(), err.Error())
}
} else {
_, err := objMgr.DeleteFixedAddress(d.Id())
if err != nil {
- return fmt.Errorf("Error Releasing IP from network block having reference (%s): %s", d.Id(), err)
+ return fmt.Errorf("Error Releasing IP from network block having reference %s: %s", d.Id(), err.Error())
}
}
d.SetId("")
- log.Printf("[DEBUG] %s: Finishing Release of allocated IP in the specified network block", resourceIPAllocationIDString(d))
return nil
}
-type resourceIPAllocationIDStringInterface interface {
- Id() string
+// Code snippet for IPv4 IP Allocation
+func resourceIPv4AllocationRequest(d *schema.ResourceData, m interface{}) error {
+ return resourceIPAllocationRequest(d, m, false)
}
-func resourceIPAllocationIDString(d resourceIPAllocationIDStringInterface) string {
- id := d.Id()
- if id == "" {
- id = ""
- }
- return fmt.Sprintf("infoblox_ip_allocation (ID = %s)", id)
+func resourceIPv4AllocationGet(d *schema.ResourceData, m interface{}) error {
+ return resourceIPAllocationGet(d, m, false)
+}
+
+func resourceIPv4AllocationUpdate(d *schema.ResourceData, m interface{}) error {
+ return resourceIPAllocationUpdate(d, m, false)
+}
+
+func resourceIPv4AllocationRelease(d *schema.ResourceData, m interface{}) error {
+ return resourceIPAllocationRelease(d, m, false)
+}
+
+func resourceIPv4Allocation() *schema.Resource {
+ ipv4Allocation := resourceIPAllocation()
+ ipv4Allocation.Create = resourceIPv4AllocationRequest
+ ipv4Allocation.Read = resourceIPv4AllocationGet
+ ipv4Allocation.Update = resourceIPv4AllocationUpdate
+ ipv4Allocation.Delete = resourceIPv4AllocationRelease
+
+ return ipv4Allocation
+}
+
+// Code snippet for IPv6 IP allocation
+func resourceIPv6AllocationRequest(d *schema.ResourceData, m interface{}) error {
+ return resourceIPAllocationRequest(d, m, true)
+}
+
+func resourceIPv6AllocationGet(d *schema.ResourceData, m interface{}) error {
+ return resourceIPAllocationGet(d, m, true)
+}
+
+func resourceIPv6AllocationUpdate(d *schema.ResourceData, m interface{}) error {
+ return resourceIPAllocationUpdate(d, m, true)
+}
+
+func resourceIPv6AllocationRelease(d *schema.ResourceData, m interface{}) error {
+ return resourceIPAllocationRelease(d, m, true)
+}
+
+func resourceIPv6Allocation() *schema.Resource {
+ ipv6Allocation := resourceIPAllocation()
+ ipv6Allocation.Create = resourceIPv6AllocationRequest
+ ipv6Allocation.Read = resourceIPv6AllocationGet
+ ipv6Allocation.Update = resourceIPv6AllocationUpdate
+ ipv6Allocation.Delete = resourceIPv6AllocationRelease
+
+ return ipv6Allocation
}
diff --git a/infoblox/resource_infoblox_ip_allocation_test.go b/infoblox/resource_infoblox_ip_allocation_test.go
index 74436cd02..a502e3931 100644
--- a/infoblox/resource_infoblox_ip_allocation_test.go
+++ b/infoblox/resource_infoblox_ip_allocation_test.go
@@ -2,29 +2,394 @@ package infoblox
import (
"fmt"
+ "reflect"
+ "sort"
+ "strings"
+ "testing"
+
"github.com/hashicorp/terraform/helper/resource"
"github.com/hashicorp/terraform/terraform"
- "github.com/infobloxopen/infoblox-go-client"
- "testing"
+ ibclient "github.com/infobloxopen/infoblox-go-client"
+)
+
+var NotFoundTexts = []string{"404 Not Found", "not found"}
+
+const (
+ eaListTypeString = iota
+ eaListTypeInt
)
-func TestAccResourceIPAllocation(t *testing.T) {
+var testAccresourceIPv4AllocationCreate = fmt.Sprintf(`
+resource "infoblox_ipv4_allocation" "foo"{
+ network_view_name="%s"
+ cidr="10.0.0.0/24"
+ ip_addr="10.0.0.1"
+ comment = "10.0.0.1 IP is allocated"
+ extensible_attributes = jsonencode({
+ "VM Name" = "tf-ec2-instance"
+ "Tenant ID" = "terraform_test_tenant"
+ Location = "Test loc."
+ Site = "Test site"
+ TestEA1 = ["text1","text2"]
+ TestEA2 = [4,5]
+ })
+ }`, testNetView)
+
+var testAccresourceIPv4AllocationUpdate = fmt.Sprintf(`
+resource "infoblox_ipv4_allocation" "foo"{
+ network_view_name="%s"
+ cidr="10.0.0.0/24"
+ ip_addr="10.0.0.1"
+ comment = "10.0.0.1 IP is allocated updated"
+ extensible_attributes = jsonencode({
+ "VM Name" = "tf-ec2-instance"
+ "Tenant ID" = "terraform_test_tenant"
+ Location = "Test loc. updated"
+ TestEA1 = "text3"
+ TestEA2 = 7
+ })
+ }`, testNetView)
+
+var testAccresourceIPv6AllocationCreate = fmt.Sprintf(`
+ resource "infoblox_ipv6_allocation" "foo"{
+ network_view_name="%s"
+ cidr="2001:db8:abcd:12::/64"
+ ip_addr="2001:db8:abcd:12::1"
+ duid="11:22:33:44:55:66"
+ comment = "2001:db8:abcd:12::1 IP is allocated"
+ extensible_attributes = jsonencode({
+ "VM Name" = "tf-ec2-instance-ipv6"
+ "Tenant ID" = "terraform_test_tenant"
+ Location = "Test loc."
+ Site = "Test site"
+ TestEA1 = ["text1","text2"]
+ TestEA2 = [4,5]
+ })
+ }`, testNetView)
+
+var testAccresourceIPv6AllocationUpdate = fmt.Sprintf(`
+ resource "infoblox_ipv6_allocation" "foo"{
+ network_view_name="%s"
+ cidr="2001:db8:abcd:12::/64"
+ ip_addr="2001:db8:abcd:12::1"
+ duid="11:22:33:44:55:66"
+ comment = "2001:db8:abcd:12::1 IP is allocated updated"
+ extensible_attributes = jsonencode({
+ "VM Name" = "tf-ec2-instance-ipv6"
+ "Tenant ID" = "terraform_test_tenant"
+ Location = "Test loc. updated"
+ TestEA1 = "text3"
+ TestEA2 = 7
+ })
+ }`, testNetView)
+
+func isNotFoundError(err error) bool {
+ if _, notFoundErr := err.(*ibclient.NotFoundError); notFoundErr {
+ return true
+ }
+
+ // TODO: uncomment when infoblox-go-client will handle NotFoundError separately.
+ //return false
+
+ errText := err.Error()
+ for _, text := range NotFoundTexts {
+ if strings.Contains(errText, text) {
+ return true
+ }
+ }
+
+ return false
+}
+
+func typesEqual(a, b interface{}) bool {
+ return reflect.TypeOf(a) == reflect.TypeOf(b)
+}
+
+func sortList(s interface{}) error {
+ switch slice := s.(type) {
+ case []int:
+ sort.Ints(slice)
+ case []string:
+ stringSlice := s.([]string)
+ sort.Strings(stringSlice)
+ default:
+ return fmt.Errorf("expected value is of an unsupported type")
+ }
+ return nil
+}
+
+func validateValues(actual, expected interface{}) (bool, error) {
+ switch expTyped := expected.(type) {
+ case int:
+ av := actual.(int)
+ if expTyped != av {
+ return false, nil
+ }
+ case bool:
+ av := actual.(bool)
+ if expTyped != av {
+ return false, nil
+ }
+ case string:
+ av := actual.(string)
+ if expTyped != av {
+ return false, nil
+ }
+ default:
+ return false, fmt.Errorf("expected value '%+v' is of an unsupported type", expected)
+ }
+
+ return true, nil
+}
+
+func validateEAs(actualEAs, expectedEAs ibclient.EA) error {
+ for eaKey, expEaVal := range expectedEAs {
+ actEaVal, found := actualEAs[eaKey]
+ if !found {
+ return fmt.Errorf(
+ "a value for extensible attribute '%s' not found, but expected to exist", eaKey)
+ }
+
+ if !typesEqual(actEaVal, expEaVal) {
+ return fmt.Errorf("actual and expected values for extensible attribute '%s' have unequal types", eaKey)
+ }
+
+ reflActEaVal := reflect.ValueOf(actEaVal)
+ switch reflActEaVal.Kind() {
+ case reflect.Slice:
+ var eaListType int
+
+ switch actEaVal.(type) {
+ case []int:
+ eaListType = eaListTypeInt
+ case []string:
+ eaListType = eaListTypeString
+ default:
+ return fmt.Errorf("unsupported type for 'extensible_attributes' field value: %+v", actEaVal)
+ }
+
+ reflExpEaVal := reflect.ValueOf(expEaVal)
+ if reflActEaVal.Len() != reflExpEaVal.Len() {
+ return fmt.Errorf(
+ "the value of extensible attribute '%s' is not equal to the expected one", eaKey)
+ }
+ numItems := reflExpEaVal.Len()
+ if numItems == 0 {
+ return nil
+ }
+ if err := sortList(actEaVal.(interface{})); err != nil {
+ return err
+ }
+ if err := sortList(expEaVal.(interface{})); err != nil {
+ return err
+ }
+
+ getElemFunc := func(slice interface{}, idx int) interface{} {
+ switch eaListType {
+ case eaListTypeInt:
+ return slice.([]int)[idx]
+ case eaListTypeString:
+ return slice.([]string)[idx]
+ default:
+ panic("unexpected slice item's type")
+ }
+ }
+
+ for i := 0; i < numItems; i++ {
+ expVal := getElemFunc(expEaVal, i)
+ actVal := getElemFunc(actEaVal, i)
+ equal, err := validateValues(actVal, expVal)
+ if err != nil {
+ return err
+ }
+ if !equal {
+ return fmt.Errorf(
+ "the value for extensible attribute '%v' is '%v' but expected to be '%v'",
+ eaKey, actEaVal, expEaVal)
+ }
+ return nil
+ }
+ return nil
+ default:
+ equal, err := validateValues(actEaVal, expEaVal)
+ if err != nil {
+ return err
+ }
+ if !equal {
+ return fmt.Errorf(
+ "the value for extensible attribute '%v' is '%v' but expected to be '%v'",
+ eaKey, actEaVal, expEaVal)
+ }
+ }
+ }
+
+ return nil
+}
+
+func validateIPAllocation(
+ resourceName string,
+ expectedValue *ibclient.FixedAddress) resource.TestCheckFunc {
+ return func(s *terraform.State) error {
+ res, found := s.RootModule().Resources[resourceName]
+ if !found {
+ return fmt.Errorf("not found: %s", resourceName)
+ }
+
+ id := res.Primary.ID
+ if id == "" {
+ return fmt.Errorf("ID is not set")
+ }
+
+ connector := testAccProvider.Meta().(ibclient.IBConnector)
+ objMgr := ibclient.NewObjectManager(
+ connector,
+ "terraform_test",
+ "terraform_test_tenant")
+ ipAlloc, err := objMgr.GetFixedAddressByRef(id)
+ if err != nil {
+ if isNotFoundError(err) {
+ if expectedValue == nil {
+ return nil
+ }
+ return fmt.Errorf("object with ID '%s' not found, but expected to exist", id)
+ }
+ }
+ expNv := expectedValue.NetviewName
+ if ipAlloc.NetviewName != expNv {
+ return fmt.Errorf(
+ "the value of 'network_view_name' field is '%s', but expected '%s'",
+ ipAlloc.NetviewName, expNv)
+ }
+
+ expComment := expectedValue.Comment
+ if ipAlloc.Comment != expComment {
+ return fmt.Errorf(
+ "the value of 'comment' field is '%s', but expected '%s'",
+ ipAlloc.Comment, expComment)
+ }
+
+ expIPv4Address := expectedValue.IPv4Address
+ expIPv6Address := expectedValue.IPv6Address
+ if ipAlloc.IPv4Address != expIPv4Address || ipAlloc.IPv6Address != expIPv6Address {
+ return fmt.Errorf(
+ "the value of 'IPv4Address' field is '%s', but expected '%s'or 'IPv6Address' field is '%s', but expected %s",
+ ipAlloc.IPv4Address, expIPv4Address, ipAlloc.IPv6Address, expIPv6Address)
+ }
+
+ // the rest is about extensible attributes
+ expectedEAs := expectedValue.Ea
+ if expectedEAs == nil && ipAlloc.Ea != nil {
+ return fmt.Errorf(
+ "the object with ID '%s' has 'extensible_attributes' field, but it is not expected to exist", id)
+ }
+ if expectedEAs != nil && ipAlloc.Ea == nil {
+ return fmt.Errorf(
+ "the object with ID '%s' has no 'extensible_attributes' field, but it is expected to exist", id)
+ }
+ if expectedEAs == nil {
+ return nil
+ }
+
+ return validateEAs(ipAlloc.Ea, expectedEAs)
+ }
+}
+
+func TestAcc_resourceIPAllocation_ipv4(t *testing.T) {
+ resource.Test(t, resource.TestCase{
+ PreCheck: func() { testAccPreCheck(t) },
+ Providers: testAccProviders,
+ CheckDestroy: testAccCheckIPAllocationDestroy,
+ Steps: []resource.TestStep{
+ {
+ Config: testAccresourceIPv4AllocationCreate,
+ Check: validateIPAllocation(
+ "infoblox_ipv4_allocation.foo",
+ &ibclient.FixedAddress{
+ NetviewName: testNetView,
+ Cidr: "10.0.0.0/24",
+ Comment: "10.0.0.1 IP is allocated",
+ IPv4Address: "10.0.0.1",
+ Ea: ibclient.EA{
+ "Tenant ID": "terraform_test_tenant",
+ "VM Name": "tf-ec2-instance",
+ "Location": "Test loc.",
+ "Site": "Test site",
+ "TestEA1": []string{"text1", "text2"},
+ "TestEA2": []int{4, 5},
+ },
+ },
+ ),
+ },
+ {
+ Config: testAccresourceIPv4AllocationUpdate,
+ Check: validateIPAllocation(
+ "infoblox_ipv4_allocation.foo",
+ &ibclient.FixedAddress{
+ NetviewName: testNetView,
+ Cidr: "10.0.0.0/24",
+ Comment: "10.0.0.1 IP is allocated updated",
+ IPv4Address: "10.0.0.1",
+ Ea: ibclient.EA{
+ "Tenant ID": "terraform_test_tenant",
+ "VM Name": "tf-ec2-instance",
+ "Location": "Test loc. updated",
+ // lists which contain ony one element are reduced by NIOS to a single-value element
+ "TestEA1": "text3",
+ "TestEA2": 7,
+ },
+ },
+ ),
+ },
+ },
+ })
+}
+func TestAcc_resourceIPAllocation_ipv6(t *testing.T) {
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckIPAllocationDestroy,
Steps: []resource.TestStep{
- resource.TestStep{
- Config: testAccresourceIPAllocationCreate,
- Check: resource.ComposeTestCheckFunc(
- testAccIPExists(t, "infoblox_ip_allocation.foo", "10.0.0.1/24", "10.0.0.1", "default", "demo-network"),
+ {
+ Config: testAccresourceIPv6AllocationCreate,
+ Check: validateIPAllocation(
+ "infoblox_ipv6_allocation.foo",
+ &ibclient.FixedAddress{
+ NetviewName: testNetView,
+ Cidr: "2001:db8:abcd:12::/64",
+ Comment: "2001:db8:abcd:12::1 IP is allocated",
+ IPv6Address: "2001:db8:abcd:12::1",
+ Duid: "11:22:33:44:55:66",
+ Ea: ibclient.EA{
+ "Tenant ID": "terraform_test_tenant",
+ "VM Name": "tf-ec2-instance-ipv6",
+ "Location": "Test loc.",
+ "Site": "Test site",
+ "TestEA1": []string{"text1", "text2"},
+ "TestEA2": []int{4, 5},
+ },
+ },
),
},
- resource.TestStep{
- Config: testAccresourceIPAllocationUpdate,
- Check: resource.ComposeTestCheckFunc(
- testAccIPExists(t, "infoblox_ip_allocation.foo", "10.0.0.1/24", "10.0.0.1", "default", "demo-network"),
+ {
+ Config: testAccresourceIPv6AllocationUpdate,
+ Check: validateIPAllocation(
+ "infoblox_ipv6_allocation.foo",
+ &ibclient.FixedAddress{
+ NetviewName: testNetView,
+ Cidr: "2001:db8:abcd:12::/64",
+ Comment: "2001:db8:abcd:12::1 IP is allocated updated",
+ IPv6Address: "2001:db8:abcd:12::1",
+ Duid: "11:22:33:44:55:66",
+ Ea: ibclient.EA{
+ "Tenant ID": "terraform_test_tenant",
+ "VM Name": "tf-ec2-instance-ipv6",
+ "Location": "Test loc. updated",
+ // lists which contain ony one element are reduced by NIOS to a single-value element
+ "TestEA1": "text3",
+ "TestEA2": 7,
+ },
+ },
),
},
},
@@ -32,57 +397,25 @@ func TestAccResourceIPAllocation(t *testing.T) {
}
func testAccCheckIPAllocationDestroy(s *terraform.State) error {
- meta := testAccProvider.Meta()
+ connector := testAccProvider.Meta().(ibclient.IBConnector)
+ objMgr := ibclient.NewObjectManager(
+ connector,
+ "terraform_test",
+ "terraform_test_tenant")
for _, rs := range s.RootModule().Resources {
- if rs.Type != "resource_ip_allocation" {
+ if rs.Type != "infoblox_ipv4_allocation" && rs.Type != "infoblox_ipv6_allocation" {
continue
}
- Connector := meta.(*ibclient.Connector)
- objMgr := ibclient.NewObjectManager(Connector, "terraform_test", "test")
- recordName, _ := objMgr.GetFixedAddress("default", "10.0.0.0/24", "10.0.0.2", "")
- if recordName == nil {
- return fmt.Errorf("record not found")
- }
-
- }
- return nil
-}
-func testAccIPExists(t *testing.T, n string, cidr string, ipAddr string, networkViewName string, recordName string) resource.TestCheckFunc {
- return func(s *terraform.State) error {
- rs, ok := s.RootModule().Resources[n]
- if !ok {
- return fmt.Errorf("Not found:%s", n)
- }
- if rs.Primary.ID == "" {
- return fmt.Errorf("No ID i set")
+ res, err := objMgr.GetFixedAddressByRef(rs.Primary.ID)
+ if err != nil {
+ if isNotFoundError(err) {
+ continue
+ }
+ return err
}
- meta := testAccProvider.Meta()
- Connector := meta.(*ibclient.Connector)
- objMgr := ibclient.NewObjectManager(Connector, "terraform_test", "test")
-
- recordName, _ := objMgr.GetFixedAddress(networkViewName, cidr, ipAddr, "")
- if recordName != nil {
- return fmt.Errorf("record not found")
+ if res != nil {
+ return fmt.Errorf("object with ID '%s' remains", rs.Primary.ID)
}
-
- return nil
}
+ return nil
}
-
-var testAccresourceIPAllocationCreate = fmt.Sprintf(`
-resource "infoblox_ip_allocation" "foo"{
- network_view_name="default"
- vm_name="test-name"
- cidr="10.0.0.0/24"
- ip_addr="10.0.0.1"
- tenant_id="foo"
- }`)
-
-var testAccresourceIPAllocationUpdate = fmt.Sprintf(`
-resource "infoblox_ip_allocation" "foo"{
- network_view_name="default"
- vm_name="test-name"
- cidr="10.0.0.0/24"
- ip_addr="10.0.0.1"
- tenant_id="foo"
- }`)
diff --git a/infoblox/resource_infoblox_ip_association.go b/infoblox/resource_infoblox_ip_association.go
index ba9437aad..1a2c934b9 100644
--- a/infoblox/resource_infoblox_ip_association.go
+++ b/infoblox/resource_infoblox_ip_association.go
@@ -1,8 +1,8 @@
package infoblox
import (
+ "encoding/json"
"fmt"
- "log"
"strings"
"github.com/hashicorp/terraform/helper/schema"
@@ -11,22 +11,34 @@ import (
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,
Default: "default",
- Description: "Network view name available in Nios server.",
+ Description: "Network view name of NIOS server.",
+ },
+ "enable_dns": &schema.Schema{
+ Type: schema.TypeBool,
+ Optional: true,
+ Default: true,
+ Description: "flag that defines if the host record is to be used for DNS Purposes",
+ },
+ "enable_dhcp": {
+ Type: schema.TypeBool,
+ Optional: true,
+ Default: false,
+ Description: "flag that defines if the host record is to be used for IPAM Purposes.",
},
- "vm_name": &schema.Schema{
+ "dns_view": &schema.Schema{
Type: schema.TypeString,
Optional: true,
- Description: "The name of the vm.",
+ Description: "view in which record has to be created.",
+ },
+ "zone": &schema.Schema{
+ Type: schema.TypeString,
+ Optional: true,
+ Description: "zone under which record has been created.",
},
"cidr": &schema.Schema{
Type: schema.TypeString,
@@ -36,32 +48,34 @@ func resourceIPAssociation() *schema.Resource {
"ip_addr": &schema.Schema{
Type: schema.TypeString,
Required: true,
- Description: "IP address your instance in cloud.",
+ Description: "IP address of cloud instance.",
},
"mac_addr": &schema.Schema{
Type: schema.TypeString,
- Required: true,
- Description: "mac address of your instance in cloud.",
+ Optional: true,
+ Description: "mac address of cloud instance.",
},
- "dns_view": &schema.Schema{
+ "duid": &schema.Schema{
Type: schema.TypeString,
Optional: true,
- Description: "view in which record has to be created.",
+ Description: "DHCP unique identifier for IPv6.",
},
- "zone": &schema.Schema{
+ "host_name": {
Type: schema.TypeString,
- Optional: true,
- Description: "zone under which record has been created.",
+ Required: true,
+ Description: "The host name",
},
- "vm_id": &schema.Schema{
+ "comment": {
Type: schema.TypeString,
+ Default: "",
Optional: true,
- Description: "instance id.",
+ Description: "A description of the IP association.",
},
- "tenant_id": &schema.Schema{
+ "extensible_attributes": {
Type: schema.TypeString,
- Required: true,
- Description: "Unique identifier of your tenant in cloud.",
+ Default: "",
+ Optional: true,
+ Description: "The Extensible attributes of the network container to be added/updated, as a map in JSON format",
},
},
}
@@ -70,153 +84,421 @@ func resourceIPAssociation() *schema.Resource {
//This method has an update call for the reason that,we are creating
//a reservation which doesnt have the details of the mac address
//at the beginig and 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
+//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))
+func resourceIPAssociationCreate(d *schema.ResourceData, m interface{}, isIPv6 bool) error {
- if err := Resource(d, m); err != nil {
+ if err := Resource(d, m, isIPv6); err != nil {
return err
}
- log.Printf("[DEBUG] %s:completing Association of IP address in specified network block", resourceIPAssociationIDString(d))
- return resourceIPAssociationRead(d, m)
+ return nil
}
-func resourceIPAssociationUpdate(d *schema.ResourceData, m interface{}) error {
- log.Printf("[DEBUG] %s:update operation on Association of IP address in specified network block", resourceIPAssociationIDString(d))
+func resourceIPAssociationUpdate(d *schema.ResourceData, m interface{}, isIPv6 bool) error {
- if err := Resource(d, m); err != nil {
+ if err := Resource(d, m, isIPv6); err != nil {
return err
}
- log.Printf("[DEBUG] %s:completing updation on Association of IP address in specified network block", resourceIPAssociationIDString(d))
- return resourceIPAssociationRead(d, m)
+ return nil
}
func resourceIPAssociationRead(d *schema.ResourceData, m interface{}) error {
- log.Printf("[DEBUG] %s:Reading the required IP from network block", resourceIPAllocationIDString(d))
- tenantID := d.Get("tenant_id").(string)
+ enableDns := d.Get("enable_dns").(bool)
+ enableDhcp := d.Get("enable_dhcp").(bool)
+ hostName := d.Get("host_name").(string)
+
cidr := d.Get("cidr").(string)
- zone := d.Get("zone").(string)
dnsView := d.Get("dns_view").(string)
- connector := m.(*ibclient.Connector)
+ zone := d.Get("zone").(string)
+ extAttrJSON := d.Get("extensible_attributes").(string)
+ extAttrs := make(map[string]interface{})
+ if extAttrJSON != "" {
+ if err := json.Unmarshal([]byte(extAttrJSON), &extAttrs); err != nil {
+ return fmt.Errorf("cannot process 'extensible_attributes' field: %s", err.Error())
+ }
+ }
+
+ var tenantID string
+ for attrName, attrValueInf := range extAttrs {
+ attrValue, _ := attrValueInf.(string)
+ if attrName == "Tenant ID" {
+ tenantID = attrValue
+ }
+ }
+
+ if hostName == "" {
+ return fmt.Errorf("'host_name' is mandatory to be passed for Association of IP")
+ }
+ connector := m.(*ibclient.Connector)
objMgr := ibclient.NewObjectManager(connector, "Terraform", tenantID)
- if (zone != "" || len(zone) != 0) && (dnsView != "" || len(dnsView) != 0) {
+ if (zone != "" || len(zone) != 0) && (dnsView != "" || len(dnsView) != 0) && enableDns {
obj, err := objMgr.GetHostRecordByRef(d.Id())
if err != nil {
- return fmt.Errorf("Error getting IP from network block(%s): %s", cidr, err)
+ return fmt.Errorf("Error getting IP from network block %s: %s", cidr, err.Error())
+ }
+ d.SetId(obj.Ref)
+ } else if enableDhcp || !enableDns {
+ obj, err := objMgr.GetHostRecordByRef(d.Id())
+ if err != nil {
+ return fmt.Errorf("Error getting IP from network block %s: %s", cidr, err.Error())
}
d.SetId(obj.Ref)
} else {
obj, err := objMgr.GetFixedAddressByRef(d.Id())
if err != nil {
- return fmt.Errorf("Error getting IP from network block(%s): %s", cidr, err)
+ return fmt.Errorf("Error getting IP from network block %s: %s", cidr, err.Error())
}
d.SetId(obj.Ref)
}
- log.Printf("[DEBUG] %s: Completed Reading IP from the network block", resourceIPAllocationIDString(d))
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))
- matchClient := "MAC_ADDRESS"
+func resourceIPAssociationDelete(d *schema.ResourceData, m interface{}, isIPv6 bool) error {
+
ipAddr := d.Get("ip_addr").(string)
- vmID := d.Get("vm_id").(string)
- vmName := d.Get("vm_name").(string)
- tenantID := d.Get("tenant_id").(string)
- zone := d.Get("zone").(string)
+ hostName := d.Get("host_name").(string)
+
+ enableDns := d.Get("enable_dns").(bool)
+ enableDhcp := d.Get("enable_dhcp").(bool)
dnsView := d.Get("dns_view").(string)
+ zone := d.Get("zone").(string)
+ duid := d.Get("duid").(string)
- connector := m.(*ibclient.Connector)
+ comment := d.Get("comment").(string)
+ extAttrJSON := d.Get("extensible_attributes").(string)
+ extAttrs := make(map[string]interface{})
+ if extAttrJSON != "" {
+ if err := json.Unmarshal([]byte(extAttrJSON), &extAttrs); err != nil {
+ return fmt.Errorf("cannot process 'extensible_attributes' field: %s", err.Error())
+ }
+ }
+ var tenantID string
+ for attrName, attrValueInf := range extAttrs {
+ attrValue, _ := attrValueInf.(string)
+ if attrName == "Tenant ID" {
+ tenantID = attrValue
+ }
+ }
+
+ if hostName == "" {
+ return fmt.Errorf("'host_name' is mandatory to be passed for removal of Association")
+ }
+
+ var recFQDN string
+ if len(zone) > 0 {
+ recFQDN = hostName + "." + zone
+ } else {
+ recFQDN = hostName
+ }
ZeroMacAddr := "00:00:00:00:00:00"
+ connector := m.(*ibclient.Connector)
objMgr := ibclient.NewObjectManager(connector, "Terraform", tenantID)
- if (zone != "" || len(zone) != 0) && (dnsView != "" || len(dnsView) != 0) {
- _, err := objMgr.UpdateHostRecord(d.Id(), ipAddr, ZeroMacAddr, vmID, vmName)
- if err != nil {
- return fmt.Errorf("Error Releasing IP from network block having reference (%s): %s", d.Id(), err)
+ if (zone != "" || len(zone) != 0) && (dnsView != "" || len(dnsView) != 0) && enableDns {
+ if isIPv6 {
+ obj, err := objMgr.UpdateHostRecord(
+ d.Id(),
+ enableDns,
+ enableDhcp,
+ recFQDN,
+ "", ipAddr,
+ "", duid,
+ comment,
+ extAttrs, []string{})
+ if err != nil {
+ return fmt.Errorf("Error updating Host record of IP from network block having reference %s: %s", d.Id(), err.Error())
+ }
+ d.SetId(obj.Ref)
+ } else {
+ obj, err := objMgr.UpdateHostRecord(
+ d.Id(),
+ enableDns,
+ enableDhcp,
+ recFQDN,
+ ipAddr, "",
+ ZeroMacAddr, "",
+ comment,
+ extAttrs, []string{})
+ if err != nil {
+ return fmt.Errorf("Error updating Host record of IP from network block having reference %s: %s", d.Id(), err.Error())
+ }
+ d.SetId(obj.Ref)
+ }
+ } else if enableDhcp || !enableDns {
+ // default value of enableDns is true. When user sets enableDhcp as true and does not pass a enableDns flag
+ enableDns = false
+
+ if isIPv6 {
+ obj, err := objMgr.UpdateHostRecord(
+ d.Id(),
+ enableDns,
+ enableDhcp,
+ recFQDN,
+ "", ipAddr,
+ "", duid,
+ comment,
+ extAttrs, []string{})
+ if err != nil {
+ return fmt.Errorf("Error updating Host record of IP from network block having reference %s: %s", d.Id(), err.Error())
+ }
+ d.SetId(obj.Ref)
+ } else {
+ obj, err := objMgr.UpdateHostRecord(
+ d.Id(),
+ enableDns,
+ enableDhcp,
+ recFQDN,
+ ipAddr, "",
+ ZeroMacAddr, "",
+ comment,
+ extAttrs, []string{})
+ if err != nil {
+ return fmt.Errorf("Error updating Host record of IP from network block having reference %s: %s", d.Id(), err.Error())
+ }
+ d.SetId(obj.Ref)
}
- d.SetId("")
} else {
- _, err := objMgr.UpdateFixedAddress(d.Id(), matchClient, ZeroMacAddr, "", "")
- if err != nil {
- return fmt.Errorf("Error Releasing IP from network block having reference (%s): %s", d.Id(), err)
+ matchClient := "MAC_ADDRESS"
+ if isIPv6 {
+ matchClient = ""
+ _, err := objMgr.UpdateFixedAddress(d.Id(), hostName, matchClient, duid, comment, extAttrs)
+ if err != nil {
+ return fmt.Errorf("Error Releasing IP from network block having reference %s: %s", d.Id(), err.Error())
+ }
+ } else {
+ _, err := objMgr.UpdateFixedAddress(d.Id(), hostName, matchClient, ZeroMacAddr, comment, extAttrs)
+ if err != nil {
+ return fmt.Errorf("Error Releasing IP from network block having reference %s: %s", d.Id(), err.Error())
+ }
}
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 = ""
- }
- return fmt.Sprintf("infoblox_mac_allocation (ID = %s)", id)
-}
+func Resource(d *schema.ResourceData, m interface{}, isIPv6 bool) error {
-func Resource(d *schema.ResourceData, m interface{}) error {
-
- matchClient := "MAC_ADDRESS"
networkViewName := d.Get("network_view_name").(string)
- Name := d.Get("vm_name").(string)
- ipAddr := d.Get("ip_addr").(string)
+ enableDns := d.Get("enable_dns").(bool)
+ enableDhcp := d.Get("enable_dhcp").(bool)
+ dnsView := d.Get("dns_view").(string)
+ zone := d.Get("zone").(string)
+ hostName := d.Get("host_name").(string)
+
cidr := d.Get("cidr").(string)
+ ipAddr := d.Get("ip_addr").(string)
macAddr := d.Get("mac_addr").(string)
- tenantID := d.Get("tenant_id").(string)
- vmID := d.Get("vm_id").(string)
- zone := d.Get("zone").(string)
- dnsView := d.Get("dns_view").(string)
+ duid := d.Get("duid").(string)
- connector := m.(*ibclient.Connector)
+ comment := d.Get("comment").(string)
+ extAttrJSON := d.Get("extensible_attributes").(string)
+ extAttrs := make(map[string]interface{})
+ if extAttrJSON != "" {
+ if err := json.Unmarshal([]byte(extAttrJSON), &extAttrs); err != nil {
+ return fmt.Errorf("cannot process 'extensible_attributes' field: %s", err.Error())
+ }
+ }
+ var tenantID string
+ for attrName, attrValue := range extAttrs {
+ attrValue, _ := attrValue.(string)
+ if attrName == "Tenant ID" {
+ tenantID = attrValue
+ }
+ }
+
+ if hostName == "" {
+ return fmt.Errorf("'host_name' is mandatory to be passed for Association")
+ }
- objMgr := ibclient.NewObjectManager(connector, "Terraform", tenantID)
//conversion from bit reversed EUI-48 format to hexadecimal EUI-48 format
macAddr = strings.Replace(macAddr, "-", ":", -1)
- name := Name + "." + zone
+ var recFQDN string
+ if len(zone) > 0 {
+ recFQDN = hostName + "." + zone
+ } else {
+ recFQDN = hostName
+ }
- if (zone != "" || len(zone) != 0) && (dnsView != "" || len(dnsView) != 0) {
- hostRecordObj, err := objMgr.GetHostRecord(name)
- if err != nil {
- return fmt.Errorf("GetHostRecord failed from network block(%s):%s", cidr, err)
- }
- if hostRecordObj == nil {
- return fmt.Errorf("HostRecord %s not found.", name)
+ connector := m.(*ibclient.Connector)
+ objMgr := ibclient.NewObjectManager(connector, "Terraform", tenantID)
+
+ //var err error
+ if (zone != "" || len(zone) != 0) && (dnsView != "" || len(dnsView) != 0) && enableDns {
+ if isIPv6 {
+ hostRecordObj, err := objMgr.GetHostRecord(recFQDN, "", ipAddr)
+ if err != nil {
+ return fmt.Errorf("GetHostRecord failed from IPv6 network block %s:%s", cidr, err.Error())
+ }
+ if hostRecordObj == nil {
+ return fmt.Errorf("HostRecord %s not found.", recFQDN)
+ }
+ Obj, err := objMgr.UpdateHostRecord(
+ hostRecordObj.Ref,
+ enableDns,
+ enableDhcp,
+ recFQDN,
+ "", ipAddr,
+ "", duid,
+ comment,
+ extAttrs, []string{})
+ if err != nil {
+ return fmt.Errorf("UpdateHost Record failed from IPv6 network block %s: %s", cidr, err.Error())
+ }
+ d.SetId(Obj.Ref)
+ } else {
+ hostRecordObj, err := objMgr.GetHostRecord(recFQDN, ipAddr, "")
+ if err != nil {
+ return fmt.Errorf("GetHostRecord failed from IPv4 network block %s:%s", cidr, err.Error())
+ }
+ if hostRecordObj == nil {
+ return fmt.Errorf("HostRecord %s not found.", recFQDN)
+ }
+ Obj, err := objMgr.UpdateHostRecord(
+ hostRecordObj.Ref,
+ enableDns,
+ enableDhcp,
+ recFQDN,
+ ipAddr, "",
+ macAddr, "",
+ comment,
+ extAttrs, []string{})
+ if err != nil {
+ return fmt.Errorf("UpdateHost Record failed from network block %s:%s", cidr, err.Error())
+ }
+ d.SetId(Obj.Ref)
}
- _, err = objMgr.UpdateHostRecord(hostRecordObj.Ref, ipAddr, macAddr, vmID, Name)
- if err != nil {
- return fmt.Errorf("UpdateHost Record error from network block(%s):%s", cidr, err)
+ } else if enableDhcp || !enableDns {
+ // default value of enableDns is true. When user sets enableDhcp as true and does not pass a enableDns flag
+ enableDns = false
+
+ if isIPv6 {
+ hostRecordObj, err := objMgr.GetHostRecord(recFQDN, "", ipAddr)
+ if err != nil {
+ return fmt.Errorf("GetHostRecord failed from IPv6 network block %s:%s", cidr, err.Error())
+ }
+ if hostRecordObj == nil {
+ return fmt.Errorf("HostRecord %s not found.", recFQDN)
+ }
+ Obj, err := objMgr.UpdateHostRecord(
+ hostRecordObj.Ref,
+ enableDns,
+ enableDhcp,
+ recFQDN,
+ "", ipAddr,
+ "", duid,
+ comment,
+ extAttrs, []string{})
+ if err != nil {
+ return fmt.Errorf("UpdateHost Record failed from IPv6 network block %s: %s", cidr, err.Error())
+ }
+ d.SetId(Obj.Ref)
+ } else {
+ hostRecordObj, err := objMgr.GetHostRecord(recFQDN, ipAddr, "")
+ if err != nil {
+ return fmt.Errorf("GetHostRecord failed from IPv4 network block %s:%s", cidr, err.Error())
+ }
+ if hostRecordObj == nil {
+ return fmt.Errorf("HostRecord %s not found.", recFQDN)
+ }
+ Obj, err := objMgr.UpdateHostRecord(
+ hostRecordObj.Ref,
+ enableDns,
+ enableDhcp,
+ recFQDN,
+ ipAddr, "",
+ macAddr, "",
+ comment,
+ extAttrs, []string{})
+ if err != nil {
+ return fmt.Errorf("UpdateHost Record failed from network block %s:%s", cidr, err.Error())
+ }
+ d.SetId(Obj.Ref)
}
- d.SetId(hostRecordObj.Ref)
} else {
- fixedAddressObj, err := objMgr.GetFixedAddress(networkViewName, cidr, ipAddr, "")
+ fixedAddressObj, err := objMgr.GetFixedAddress(networkViewName, cidr, ipAddr, isIPv6, "")
if err != nil {
- return fmt.Errorf("GetFixedAddress error from network block(%s):%s", cidr, err)
+ return fmt.Errorf("GetFixedAddress failed from network block %s:%s", cidr, err.Error())
}
if fixedAddressObj == nil {
return fmt.Errorf("FixedAddress %s not found in network %s.", ipAddr, cidr)
}
- _, err = objMgr.UpdateFixedAddress(fixedAddressObj.Ref, matchClient, macAddr, vmID, Name)
+ var macOrDuid string
+ macOrDuid = macAddr
+ matchClient := "MAC_ADDRESS"
+ if isIPv6 {
+ matchClient = ""
+ macOrDuid = duid
+ }
+ _, err = objMgr.UpdateFixedAddress(fixedAddressObj.Ref, hostName, matchClient, macOrDuid, comment, extAttrs)
if err != nil {
- return fmt.Errorf("UpdateFixedAddress error from network block(%s):%s", cidr, err)
+ return fmt.Errorf("UpdateFixedAddress error from network block %s:%s", cidr, err.Error())
}
d.SetId(fixedAddressObj.Ref)
}
return nil
}
+
+// Code snippet for IPv4 IP Association
+func resourceIPv4AssociationCreate(d *schema.ResourceData, m interface{}) error {
+ return resourceIPAssociationCreate(d, m, false)
+}
+
+func resourceIPv4AssociationGet(d *schema.ResourceData, m interface{}) error {
+ return resourceIPAssociationRead(d, m)
+}
+
+func resourceIPv4AssociationUpdate(d *schema.ResourceData, m interface{}) error {
+ return resourceIPAssociationUpdate(d, m, false)
+}
+
+func resourceIPv4AssociationDelete(d *schema.ResourceData, m interface{}) error {
+ return resourceIPAssociationDelete(d, m, false)
+}
+
+func resourceIPv4Association() *schema.Resource {
+ ipv4Association := resourceIPAssociation()
+ ipv4Association.Create = resourceIPv4AssociationCreate
+ ipv4Association.Read = resourceIPv4AssociationGet
+ ipv4Association.Update = resourceIPv4AssociationUpdate
+ ipv4Association.Delete = resourceIPv4AssociationDelete
+
+ return ipv4Association
+}
+
+// Code snippet for IPv6 IP Association
+func resourceIPv6AssociationCreate(d *schema.ResourceData, m interface{}) error {
+ return resourceIPAssociationCreate(d, m, true)
+}
+
+func resourceIPv6AssociationRead(d *schema.ResourceData, m interface{}) error {
+ return resourceIPAssociationRead(d, m)
+}
+
+func resourceIPv6AssociationUpdate(d *schema.ResourceData, m interface{}) error {
+ return resourceIPAssociationUpdate(d, m, true)
+}
+
+func resourceIPv6AssociationDelete(d *schema.ResourceData, m interface{}) error {
+ return resourceIPAssociationDelete(d, m, true)
+}
+
+func resourceIPv6Association() *schema.Resource {
+ ipv6Association := resourceIPAssociation()
+ ipv6Association.Create = resourceIPv6AssociationCreate
+ ipv6Association.Read = resourceIPv6AssociationRead
+ ipv6Association.Update = resourceIPv6AssociationUpdate
+ ipv6Association.Delete = resourceIPv6AssociationDelete
+
+ return ipv6Association
+}
diff --git a/infoblox/resource_infoblox_ip_association_test.go b/infoblox/resource_infoblox_ip_association_test.go
index ab84fb57f..2ff20a53f 100644
--- a/infoblox/resource_infoblox_ip_association_test.go
+++ b/infoblox/resource_infoblox_ip_association_test.go
@@ -2,89 +2,279 @@ package infoblox
import (
"fmt"
+ "testing"
+
"github.com/hashicorp/terraform/helper/resource"
"github.com/hashicorp/terraform/terraform"
- "github.com/infobloxopen/infoblox-go-client"
- "testing"
+ ibclient "github.com/infobloxopen/infoblox-go-client"
)
-func TestAccresourceIPAssociation(t *testing.T) {
+var testAccresourceIPv4AssociationCreate = fmt.Sprintf(`
+resource "infoblox_ipv4_association" "foo"{
+ network_view_name="%s"
+ cidr="10.0.0.0/24"
+ ip_addr="10.0.0.1"
+ mac_addr="11:22:33:44:55:66"
+ comment = "10.0.0.1 IP is associated "
+ extensible_attributes = jsonencode({
+ "VM Name" = "tf-ec2-instance"
+ "Tenant ID" = "terraform_test_tenant"
+ Location = "Test loc."
+ Site = "Test site"
+ TestEA1 = ["text1","text2"]
+ TestEA2 = [4,5]
+ })
+ }`, testNetView)
+
+var testAccresourceIPv4AssociationUpdate = fmt.Sprintf(`
+resource "infoblox_ipv4_association" "foo"{
+ network_view_name="%s"
+ cidr="10.0.0.0/24"
+ ip_addr="10.0.0.1"
+ mac_addr="11:22:33:44:55:66"
+ comment = "10.0.0.1 IP is associated updated"
+ extensible_attributes = jsonencode({
+ "VM Name" = "tf-ec2-instance"
+ "Tenant ID" = "terraform_test_tenant"
+ Location = "Test loc. updated"
+ TestEA1 = "text3"
+ TestEA2 = 7
+ })
+ }`, testNetView)
+
+var testAccresourceIPv6AssociationCreate = fmt.Sprintf(`
+ resource "infoblox_ipv6_association" "foo"{
+ network_view_name="%s"
+ cidr="2001:db8:abcd:12::/64"
+ ip_addr="2001:db8:abcd:12::1"
+ duid="11:22:33:44:55:66"
+ comment = "2001:db8:abcd:12::1 IP is associated"
+ extensible_attributes = jsonencode({
+ "VM Name" = "tf-ec2-instance-ipv6"
+ "Tenant ID" = "terraform_test_tenant"
+ Location = "Test loc."
+ Site = "Test site"
+ TestEA1 = ["text1","text2"]
+ TestEA2 = [4,5]
+ })
+ }`, testNetView)
+
+var testAccresourceIPv6AssociationUpdate = fmt.Sprintf(`
+ resource "infoblox_ipv6_association" "foo"{
+ network_view_name="%s"
+ cidr="2001:db8:abcd:12::/64"
+ ip_addr="2001:db8:abcd:12::1"
+ duid="11:22:33:44:55:66"
+ comment = "2001:db8:abcd:12::1 IP is associated updated"
+ extensible_attributes = jsonencode({
+ "VM Name" = "tf-ec2-instance-ipv6"
+ "Tenant ID" = "terraform_test_tenant"
+ Location = "Test loc. updated"
+ TestEA1 = "text3"
+ TestEA2 = 7
+ })
+ }`, testNetView)
+
+func validateIPAssociation(
+ resourceName string,
+ expectedValue *ibclient.FixedAddress) resource.TestCheckFunc {
+ return func(s *terraform.State) error {
+ res, found := s.RootModule().Resources[resourceName]
+ if !found {
+ return fmt.Errorf("not found: %s", resourceName)
+ }
+
+ id := res.Primary.ID
+ if id == "" {
+ return fmt.Errorf("ID is not set")
+ }
+ connector := testAccProvider.Meta().(ibclient.IBConnector)
+ objMgr := ibclient.NewObjectManager(
+ connector,
+ "terraform_test",
+ "terraform_test_tenant")
+ ipAsso, err := objMgr.GetFixedAddressByRef(id)
+ if err != nil {
+ if isNotFoundError(err) {
+ if expectedValue == nil {
+ return nil
+ }
+ return fmt.Errorf("object with ID '%s' not found, but expected to exist", id)
+ }
+ }
+ expNv := expectedValue.NetviewName
+ if ipAsso.NetviewName != expNv {
+ return fmt.Errorf(
+ "the value of 'network_view_name' field is '%s', but expected '%s'",
+ ipAsso.NetviewName, expNv)
+ }
+
+ expComment := expectedValue.Comment
+ if ipAsso.Comment != expComment {
+ return fmt.Errorf(
+ "the value of 'comment' field is '%s', but expected '%s'",
+ ipAsso.Comment, expComment)
+ }
+
+ expIPv4Address := expectedValue.IPv4Address
+ expIPv6Address := expectedValue.IPv6Address
+ if ipAsso.IPv4Address != expIPv4Address || ipAsso.IPv6Address != expIPv6Address {
+ return fmt.Errorf(
+ "the value of 'IPv4Address' field is '%s', but expected '%s' or the value of 'IPv6Address' field is '%s', but expected '%s' ",
+ ipAsso.IPv4Address, expIPv4Address, ipAsso.IPv6Address, expIPv6Address)
+ }
+
+ expMACAddress := expectedValue.Mac
+ expDUID := expectedValue.Duid
+ if ipAsso.Mac != expMACAddress || ipAsso.Duid != expDUID {
+ return fmt.Errorf(
+ "the value of 'IPv4Address' field is '%s', but expected '%s' or the value of 'IPv6Address' field is '%s', but expected '%s' ",
+ ipAsso.IPv4Address, expIPv4Address, ipAsso.IPv6Address, expIPv6Address)
+ }
+
+ // the rest is about extensible attributes
+ expectedEAs := expectedValue.Ea
+ if expectedEAs == nil && ipAsso.Ea != nil {
+ return fmt.Errorf(
+ "the object with ID '%s' has 'extensible_attributes' field, but it is not expected to exist", id)
+ }
+ if expectedEAs != nil && ipAsso.Ea == nil {
+ return fmt.Errorf(
+ "the object with ID '%s' has no 'extensible_attributes' field, but it is expected to exist", id)
+ }
+ if expectedEAs == nil {
+ return nil
+ }
+
+ return validateEAs(ipAsso.Ea, expectedEAs)
+ }
+}
+
+func TestAcc_resourceipAssociation_ipv4(t *testing.T) {
+ resource.Test(t, resource.TestCase{
+ PreCheck: func() { testAccPreCheck(t) },
+ Providers: testAccProviders,
+ CheckDestroy: testAccCheckIPAssociationDestroy,
+ Steps: []resource.TestStep{
+ {
+ Config: testAccresourceIPv4AllocationCreate,
+ Check: validateIPAssociation(
+ "infoblox_ipv4_association.foo",
+ &ibclient.FixedAddress{
+ NetviewName: testNetView,
+ Cidr: "10.0.0.0/24",
+ Comment: "10.0.0.1 IP is associated",
+ IPv4Address: "10.0.0.1",
+ Mac: "11:22:33:44:55:66",
+ Ea: ibclient.EA{
+ "Tenant ID": "terraform_test_tenant",
+ "VM Name": "tf-ec2-instance",
+ "Location": "Test loc.",
+ "Site": "Test site",
+ "TestEA1": []string{"text1", "text2"},
+ "TestEA2": []int{4, 5},
+ },
+ },
+ ),
+ },
+ {
+ Config: testAccresourceIPv4AssociationUpdate,
+ Check: validateIPAssociation(
+ "infoblox_ipv4_association.foo",
+ &ibclient.FixedAddress{
+ NetviewName: testNetView,
+ Cidr: "10.0.0.0/24",
+ Comment: "10.0.0.1 IP is allocated updated",
+ IPv4Address: "10.0.0.1",
+ Mac: "11:22:33:44:55:66",
+ Ea: ibclient.EA{
+ "Tenant ID": "terraform_test_tenant",
+ "VM Name": "tf-ec2-instance",
+ "Location": "Test loc. updated",
+ // lists which contain ony one element are reduced by NIOS to a single-value element
+ "TestEA1": "text3",
+ "TestEA2": 7,
+ },
+ },
+ ),
+ },
+ },
+ })
+}
+
+func TestAcc_resourceIPAssociation_ipv6(t *testing.T) {
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
- CheckDestroy: testAccCheckRecordHostDestroy,
+ CheckDestroy: testAccCheckIPAssociationDestroy,
Steps: []resource.TestStep{
- resource.TestStep{
- Config: testAccresourceIPAssociationCreate,
- Check: resource.ComposeTestCheckFunc(
- testAccRecordHostExists(t, "infoblox_ip_association.foo", "10.0.0.0/24", "10.0.0.2", "default", "demo-network"),
+ {
+ Config: testAccresourceIPv6AssociationCreate,
+ Check: validateIPAssociation(
+ "infoblox_ipv6_association.foo",
+ &ibclient.FixedAddress{
+ NetviewName: testNetView,
+ Cidr: "2001:db8:abcd:12::/64",
+ Comment: "2001:db8:abcd:12::1 IP is associated",
+ IPv6Address: "2001:db8:abcd:12::1",
+ Duid: "11:22:33:44:55:66",
+ Ea: ibclient.EA{
+ "Tenant ID": "terraform_test_tenant",
+ "VM Name": "tf-ec2-instance-ipv6",
+ "Location": "Test loc.",
+ "Site": "Test site",
+ "TestEA1": []string{"text1", "text2"},
+ "TestEA2": []int{4, 5},
+ },
+ },
),
},
- resource.TestStep{
- Config: testAccresourceIPAssociationUpdate,
- Check: resource.ComposeTestCheckFunc(
- testAccRecordHostExists(t, "infoblox_ip_association.foo", "10.0.0.0/24", "10.0.0.22", "default", "demo-network"),
+ {
+ Config: testAccresourceIPv6AssociationUpdate,
+ Check: validateIPAssociation(
+ "infoblox_ipv6_association.foo",
+ &ibclient.FixedAddress{
+ NetviewName: testNetView,
+ Cidr: "2001:db8:abcd:12::/64",
+ Comment: "2001:db8:abcd:12::1 IP is associated updated",
+ IPv6Address: "2001:db8:abcd:12::1",
+ Duid: "11:22:33:44:55:66",
+ Ea: ibclient.EA{
+ "Tenant ID": "terraform_test_tenant",
+ "VM Name": "tf-ec2-instance-ipv6",
+ "Location": "Test loc. updated",
+ // lists which contain ony one element are reduced by NIOS to a single-value element
+ "TestEA1": "text3",
+ "TestEA2": 7,
+ },
+ },
),
},
},
})
}
-func testAccCheckRecordHostDestroy(s *terraform.State) error {
- meta := testAccProvider.Meta()
+func testAccCheckIPAssociationDestroy(s *terraform.State) error {
+ connector := testAccProvider.Meta().(ibclient.IBConnector)
+ objMgr := ibclient.NewObjectManager(
+ connector,
+ "terraform_test",
+ "terraform_test_tenant")
for _, rs := range s.RootModule().Resources {
- if rs.Type != "infoblox_ip_association" {
+ if rs.Type != "infoblox_ipv4_association" && rs.Type != "infoblox_ipv6_association" {
continue
}
- Connector := meta.(*ibclient.Connector)
- objMgr := ibclient.NewObjectManager(Connector, "terraform_test", "test")
- recordName, _ := objMgr.GetFixedAddress("default", "10.0.0.0/24", "10.0.0.2", "")
- if recordName == nil {
- return fmt.Errorf("record not found")
+ res, err := objMgr.GetFixedAddressByRef(rs.Primary.ID)
+ if err != nil {
+ if isNotFoundError(err) {
+ continue
+ }
+ return err
}
-
- }
- return nil
-}
-func testAccRecordHostExists(t *testing.T, n string, cidr string, ipAddr string, networkViewName string, recordName string) resource.TestCheckFunc {
- return func(s *terraform.State) error {
- rs, ok := s.RootModule().Resources[n]
- if !ok {
- return fmt.Errorf("Not found:%s", n)
- }
- if rs.Primary.ID == "" {
- return fmt.Errorf("No ID i set")
- }
- meta := testAccProvider.Meta()
- Connector := meta.(*ibclient.Connector)
- objMgr := ibclient.NewObjectManager(Connector, "terraform_test", "test")
-
- recordName, _ := objMgr.GetFixedAddress("default", "10.0.0.0/24", "10.0.0.2", "")
- if recordName == nil {
- return fmt.Errorf("record not found")
+ if res != nil {
+ return fmt.Errorf("object with ID '%s' remains", rs.Primary.ID)
}
-
- return nil
}
+ return nil
}
-
-var testAccresourceIPAssociationCreate = fmt.Sprintf(`
-resource "infoblox_ip_association" "foo"{
- network_view_name="default"
- vm_name="test-name"
- mac_addr="11:22:33:44:55:66"
- cidr="10.0.0.0/24"
- ip_addr="10.0.0.2"
- tenant_id="foo"
- }`)
-
-var testAccresourceIPAssociationUpdate = fmt.Sprintf(`
-resource "infoblox_ip_association" "foo"{
- network_view_name="default"
- vm_name="test-name"
- cidr="10.0.0.0/24"
- ip_addr="10.0.0.2"
- mac_addr="12:22:33:44:55:66"
- tenant_id="foo"
- }`)
diff --git a/infoblox/resource_infoblox_network.go b/infoblox/resource_infoblox_network.go
index 3060912da..e99cc903b 100644
--- a/infoblox/resource_infoblox_network.go
+++ b/infoblox/resource_infoblox_network.go
@@ -3,7 +3,6 @@ package infoblox
import (
"encoding/json"
"fmt"
- "log"
"github.com/hashicorp/terraform/helper/schema"
ibclient "github.com/infobloxopen/infoblox-go-client"
@@ -11,63 +10,54 @@ import (
func resourceNetwork() *schema.Resource {
return &schema.Resource{
- Create: resourceNetworkCreate,
- Read: resourceNetworkRead,
- Update: resourceNetworkUpdate,
- Delete: resourceNetworkDelete,
-
Schema: map[string]*schema.Schema{
- "network_view_name": &schema.Schema{
+ "network_view_name": {
Type: schema.TypeString,
Optional: true,
Default: "default",
Description: "Network view name available in NIOS Server.",
},
- "network_name": &schema.Schema{
+ "parent_cidr": {
Type: schema.TypeString,
Optional: true,
- Description: "The name of your network block.",
+ Description: "The parent network container block in cidr format to allocate from.",
},
- "cidr": &schema.Schema{
+ "allocate_prefix_len": {
+ Type: schema.TypeInt,
+ Optional: true,
+ Default: 0,
+ Description: "Set the parameter's value > 0 to allocate next available network with corresponding prefix length from the network container defined by 'parent_cidr'",
+ },
+ "cidr": {
Type: schema.TypeString,
Optional: true,
Computed: true,
Description: "The network block in cidr format.",
},
- "tenant_id": &schema.Schema{
- Type: schema.TypeString,
- Required: true,
- Description: "Unique identifier of your tenant in cloud.",
- },
- "reserve_ip": &schema.Schema{
+ "reserve_ip": {
Type: schema.TypeInt,
Optional: true,
Default: 0,
- Description: "The no of IP's you want to reserve.",
+ Description: "The number of IP's you want to reserve in IPv4 Network.",
},
- "gateway": &schema.Schema{
- Type: schema.TypeString,
- Optional: true,
- Description: "gateway ip address of your network block.By default first IPv4 address is set as gateway address.",
- Computed: true,
- },
- "allocate_prefix_len": &schema.Schema{
+ "reserve_ipv6": {
Type: schema.TypeInt,
Optional: true,
Default: 0,
- Description: "Set parameter value>0 to allocate next available network with prefix=value from network container defined by parent_cidr.",
+ Description: "The number of IP's you want to reserve in IPv6 Network",
},
- "parent_cidr": &schema.Schema{
+ "gateway": {
Type: schema.TypeString,
Optional: true,
- Description: "The parent network container block in cidr format to allocate from.",
+ Description: "Gateways's IP address of your network block. By default first IPv4 address is set as gateway address.",
+ Computed: true,
},
- "comment": &schema.Schema{
+ "comment": {
Type: schema.TypeString,
Optional: true,
Description: "A string describing the network",
},
- "extensible_attributes": &schema.Schema{
+ "extensible_attributes": {
Type: schema.TypeString,
Default: "",
Optional: true,
@@ -77,111 +67,185 @@ func resourceNetwork() *schema.Resource {
}
}
-func resourceNetworkCreate(d *schema.ResourceData, m interface{}) error {
- log.Printf("[DEBUG] %s: Beginning network block Creation", resourceNetworkIDString(d))
+func resourceNetworkCreate(d *schema.ResourceData, m interface{}, isIPv6 bool) error {
networkViewName := d.Get("network_view_name").(string)
+ parentCidr := d.Get("parent_cidr").(string)
+ prefixLen := d.Get("allocate_prefix_len").(int)
cidr := d.Get("cidr").(string)
- parent_cidr := d.Get("parent_cidr").(string)
- networkName := d.Get("network_name").(string)
reserveIP := d.Get("reserve_ip").(int)
+ reserveIPv6 := d.Get("reserve_ipv6").(int)
gateway := d.Get("gateway").(string)
- tenantID := d.Get("tenant_id").(string)
- connector := m.(*ibclient.Connector)
- prefixLen := d.Get("allocate_prefix_len").(int)
+
comment := d.Get("comment").(string)
- extensibleAttributesJSON := d.Get("extensible_attributes").(string)
- extensibleAttributes := make(map[string]interface{})
- if extensibleAttributesJSON != "" {
- if err := json.Unmarshal([]byte(extensibleAttributesJSON), &extensibleAttributes); err != nil {
- return fmt.Errorf("Cannot process 'extensible_attributes' field: %s", err.Error())
+ extAttrJSON := d.Get("extensible_attributes").(string)
+ extAttrs := make(map[string]interface{})
+ if extAttrJSON != "" {
+ if err := json.Unmarshal([]byte(extAttrJSON), &extAttrs); err != nil {
+ return fmt.Errorf("cannot process 'extensible_attributes' field: %s", err.Error())
+ }
+ }
+ var tenantID string
+ for attrName, attrValueInf := range extAttrs {
+ attrValue, _ := attrValueInf.(string)
+ if attrName == "Tenant ID" {
+ tenantID = attrValue
+ break
}
}
ZeroMacAddr := "00:00:00:00:00:00"
+ connector := m.(ibclient.IBConnector)
objMgr := ibclient.NewObjectManager(connector, "Terraform", tenantID)
ea := make(ibclient.EA)
var network *ibclient.Network
var err error
- if cidr == "" && parent_cidr != "" && prefixLen > 1 {
- network_container, err := objMgr.GetNetworkContainer(networkViewName, parent_cidr)
- if network_container == nil {
+ if cidr == "" && parentCidr != "" && prefixLen > 1 {
+ _, err := objMgr.GetNetworkContainer(networkViewName, parentCidr, isIPv6, nil)
+ if err != nil {
return fmt.Errorf(
- "Allocation of network block failed in network view (%s) : Parent network container %s not found.",
- networkViewName, parent_cidr)
-
+ "Allocation of network block within network container '%s' under network view '%s' failed: %s", parentCidr, networkViewName, err.Error())
}
- network, err = objMgr.AllocateNetwork(networkViewName, parent_cidr, uint(prefixLen), networkName, comment, extensibleAttributes)
+ network, err = objMgr.AllocateNetwork(networkViewName, parentCidr, isIPv6, uint(prefixLen), comment, extAttrs)
if err != nil {
return fmt.Errorf("Allocation of network block failed in network view (%s) : %s", networkViewName, err)
}
d.Set("cidr", network.Cidr)
} else if cidr != "" {
- network, err = objMgr.CreateNetwork(networkViewName, cidr, networkName, comment, extensibleAttributes)
+ network, err = objMgr.CreateNetwork(networkViewName, cidr, isIPv6, comment, extAttrs)
if err != nil {
return fmt.Errorf("Creation of network block failed in network view (%s) : %s", networkViewName, err)
}
} else {
- return fmt.Errorf("Creation of network block failed: neither cidr nor parent_cidr with allocate_prefix_len was specified.")
+ return fmt.Errorf("Creation of network block failed: neither cidr nor parentCidr with allocate_prefix_len was specified.")
}
- // Check whether gateway or ip address already allocated
- if gateway != "none" {
- gatewayIP, err := objMgr.GetFixedAddress(networkViewName, network.Cidr, gateway, "")
- if err == nil && gatewayIP != nil {
- fmt.Printf("Gateway already created")
- } else if gatewayIP == nil {
- gatewayIP, err = objMgr.AllocateIP(networkViewName, network.Cidr, gateway, ZeroMacAddr, "", ea)
+ if isIPv6 {
+ // We need Zeroduid since AWS mandates first 3 IPv6 addresses to be reserved
+ Zeroduid := "00"
+ for i := 1; i <= reserveIPv6; i++ {
+ Zeroduid += ":00"
+ _, err = objMgr.AllocateIP(networkViewName, network.Cidr, gateway, isIPv6, Zeroduid, "", comment, ea)
if err != nil {
- return fmt.Errorf("Gateway Creation failed in network block(%s) error: %s", network.Cidr, err)
+ return fmt.Errorf("Reservation in network block failed in network view(%s):%s", networkViewName, err)
}
}
- d.Set("gateway", gatewayIP.IPAddress)
- }
+ } else {
+ // Check whether gateway or ip address already allocated
+ if gateway != "none" {
+ gatewayIP, err := objMgr.GetFixedAddress(networkViewName, network.Cidr, gateway, false, "")
+ if err == nil && gatewayIP != nil {
+ fmt.Printf("Gateway already created")
+ } else if gatewayIP == nil {
+ gatewayIP, err = objMgr.AllocateIP(networkViewName, network.Cidr, gateway, isIPv6, ZeroMacAddr, "", comment, ea)
+ if err != nil {
+ return fmt.Errorf("Gateway Creation failed in network block(%s) error: %s", network.Cidr, err)
+ }
+ }
+ d.Set("gateway", gatewayIP.IPv4Address)
+ }
- for i := 1; i <= reserveIP; i++ {
- _, err = objMgr.AllocateIP(networkViewName, network.Cidr, gateway, ZeroMacAddr, "", ea)
- if err != nil {
- return fmt.Errorf("Reservation in network block failed in network view(%s):%s", networkViewName, err)
+ for i := 1; i <= reserveIP; i++ {
+ _, err = objMgr.AllocateIP(networkViewName, network.Cidr, gateway, isIPv6, ZeroMacAddr, "", comment, ea)
+ if err != nil {
+ return fmt.Errorf("Reservation in network block failed in network view(%s):%s", networkViewName, err)
+ }
}
- }
+ }
d.SetId(network.Ref)
-
- log.Printf("[DEBUG] %s: Creation on network block complete", resourceNetworkIDString(d))
- return resourceNetworkRead(d, m)
+ return nil
}
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)
- tenantID := d.Get("tenant_id").(string)
- connector := m.(*ibclient.Connector)
+ extAttrJSON := d.Get("extensible_attributes").(string)
+ extAttrs := make(map[string]interface{})
+ if extAttrJSON != "" {
+ if err := json.Unmarshal([]byte(extAttrJSON), &extAttrs); err != nil {
+ return fmt.Errorf("cannot process 'extensible_attributes' field: %s", err.Error())
+ }
+ }
+ var tenantID string
+ for attrName, attrValueInf := range extAttrs {
+ attrValue, _ := attrValueInf.(string)
+ if attrName == "Tenant ID" {
+ tenantID = attrValue
+ break
+ }
+ }
+ connector := m.(ibclient.IBConnector)
objMgr := ibclient.NewObjectManager(connector, "Terraform", tenantID)
- obj, err := objMgr.GetNetworkWithRef(d.Id())
+ obj, err := objMgr.GetNetworkByRef(d.Id())
if err != nil {
return fmt.Errorf("Getting Network block from network view (%s) failed : %s", networkViewName, err)
}
d.SetId(obj.Ref)
- log.Printf("[DEBUG] %s: Completed reading network block", resourceNetworkIDString(d))
return nil
}
func resourceNetworkUpdate(d *schema.ResourceData, m interface{}) error {
- return fmt.Errorf("network updation is not supported")
+ networkViewName := d.Get("network_view_name").(string)
+ extAttrJSON := d.Get("extensible_attributes").(string)
+ extAttrs := make(map[string]interface{})
+ if extAttrJSON != "" {
+ if err := json.Unmarshal([]byte(extAttrJSON), &extAttrs); err != nil {
+ return fmt.Errorf("cannot process 'extensible_attributes' field: %s", err.Error())
+ }
+ }
+ var tenantID string
+ for attrName, attrValueInf := range extAttrs {
+ attrValue, _ := attrValueInf.(string)
+ if attrName == "Tenant ID" {
+ tenantID = attrValue
+ break
+ }
+ }
+
+ connector := m.(ibclient.IBConnector)
+ objMgr := ibclient.NewObjectManager(connector, "Terraform", tenantID)
+ var Network *ibclient.Network
+
+ comment := ""
+ commentVal, commentFieldFound := d.GetOk("comment")
+ if commentFieldFound {
+ comment = commentVal.(string)
+ }
+
+ var err error
+
+ Network, err = objMgr.UpdateNetwork(d.Id(), extAttrs, comment)
+ if err != nil {
+ return fmt.Errorf("Updation of IPv4 Network under network view '%s' failed: '%s'", networkViewName, err.Error())
+ }
+
+ d.SetId(Network.Ref)
+ return nil
}
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)
- tenantID := d.Get("tenant_id").(string)
- connector := m.(*ibclient.Connector)
+ extAttrJSON := d.Get("extensible_attributes").(string)
+ extAttrs := make(map[string]interface{})
+ if extAttrJSON != "" {
+ if err := json.Unmarshal([]byte(extAttrJSON), &extAttrs); err != nil {
+ return fmt.Errorf("cannot process 'extensible_attributes' field: %s", err.Error())
+ }
+ }
+ var tenantID string
+ for attrName, attrValueInf := range extAttrs {
+ attrValue, _ := attrValueInf.(string)
+ if attrName == "Tenant ID" {
+ tenantID = attrValue
+ break
+ }
+ }
+ connector := m.(ibclient.IBConnector)
objMgr := ibclient.NewObjectManager(connector, "Terraform", tenantID)
_, err := objMgr.DeleteNetwork(d.Id())
@@ -189,19 +253,33 @@ func resourceNetworkDelete(d *schema.ResourceData, m interface{}) error {
return fmt.Errorf("Deletion of Network block failed from network view(%s): %s", networkViewName, err)
}
d.SetId("")
-
- log.Printf("[DEBUG] %s: Deletion of network block complete", resourceNetworkIDString(d))
return nil
}
-type resourceNetworkIDStringInterface interface {
- Id() string
+func resourceIPv4NetworkCreate(d *schema.ResourceData, m interface{}) error {
+ return resourceNetworkCreate(d, m, false)
}
-func resourceNetworkIDString(d resourceNetworkIDStringInterface) string {
- id := d.Id()
- if id == "" {
- id = ""
- }
- return fmt.Sprintf("infoblox_network (ID = %s)", id)
+func resourceIPv4Network() *schema.Resource {
+ nw := resourceNetwork()
+ nw.Create = resourceIPv4NetworkCreate
+ nw.Read = resourceNetworkRead
+ nw.Update = resourceNetworkUpdate
+ nw.Delete = resourceNetworkDelete
+
+ return nw
+}
+
+func resourceIPv6NetworkCreate(d *schema.ResourceData, m interface{}) error {
+ return resourceNetworkCreate(d, m, true)
+}
+
+func resourceIPv6Network() *schema.Resource {
+ nw := resourceNetwork()
+ nw.Create = resourceIPv6NetworkCreate
+ nw.Read = resourceNetworkRead
+ nw.Update = resourceNetworkUpdate
+ nw.Delete = resourceNetworkDelete
+
+ return nw
}
diff --git a/infoblox/resource_infoblox_network_container.go b/infoblox/resource_infoblox_network_container.go
new file mode 100644
index 000000000..379fa4759
--- /dev/null
+++ b/infoblox/resource_infoblox_network_container.go
@@ -0,0 +1,260 @@
+package infoblox
+
+import (
+ "encoding/json"
+ "fmt"
+
+ "github.com/hashicorp/terraform/helper/schema"
+ ibclient "github.com/infobloxopen/infoblox-go-client"
+)
+
+func resourceNetworkContainer() *schema.Resource {
+ return &schema.Resource{
+ Schema: map[string]*schema.Schema{
+ "network_view_name": {
+ Type: schema.TypeString,
+ Required: true,
+ Description: "The name of network view for the network container.",
+ },
+ "cidr": {
+ Type: schema.TypeString,
+ Required: true,
+ Description: "The network container's address, in CIDR format.",
+ },
+ "comment": {
+ Type: schema.TypeString,
+ Default: "",
+ Optional: true,
+ Description: "A description of the network container.",
+ },
+ "extensible_attributes": {
+ Type: schema.TypeString,
+ Default: "",
+ Optional: true,
+ Description: "The Extensible attributes of the network container to be added/updated, as a map in JSON format",
+ },
+ },
+ }
+}
+
+func resourceNetworkContainerCreate(d *schema.ResourceData, m interface{}, isIPv6 bool) error {
+ nvName := d.Get("network_view_name").(string)
+ cidr := d.Get("cidr").(string)
+ comment := d.Get("comment").(string)
+
+ extAttrJSON := d.Get("extensible_attributes").(string)
+ extAttrs := make(map[string]interface{})
+ if extAttrJSON != "" {
+ if err := json.Unmarshal([]byte(extAttrJSON), &extAttrs); err != nil {
+ return fmt.Errorf("cannot process 'extensible_attributes' field: %s", err.Error())
+ }
+ }
+ var tenantID string
+ for attrName, attrValueInf := range extAttrs {
+ attrValue, _ := attrValueInf.(string)
+ if attrName == "Tenant ID" {
+ tenantID = attrValue
+ break
+ }
+ }
+
+ if cidr == "" || nvName == "" {
+ return fmt.Errorf(
+ "Tenant ID, network view's name and CIDR are required to create a network container")
+ }
+
+ connector := m.(ibclient.IBConnector)
+ objMgr := ibclient.NewObjectManager(connector, "Terraform", tenantID)
+ nc, err := objMgr.CreateNetworkContainer(nvName, cidr, isIPv6, comment, extAttrs)
+ if err != nil {
+ return fmt.Errorf(
+ "creation of IPv6 network container block failed in network view '%s': %s",
+ nvName, err.Error())
+ }
+ d.SetId(nc.Ref)
+
+ return nil
+}
+
+func resourceNetworkContainerRead(d *schema.ResourceData, m interface{}) error {
+ extAttrJSON := d.Get("extensible_attributes").(string)
+ extAttrs := make(map[string]interface{})
+ if extAttrJSON != "" {
+ if err := json.Unmarshal([]byte(extAttrJSON), &extAttrs); err != nil {
+ return fmt.Errorf("cannot process 'extensible_attributes' field: %s", err.Error())
+ }
+ }
+ var tenantID string
+ for attrName, attrValueInf := range extAttrs {
+ attrValue, _ := attrValueInf.(string)
+ if attrName == "Tenant ID" {
+ tenantID = attrValue
+ break
+ }
+ }
+
+ connector := m.(ibclient.IBConnector)
+ objMgr := ibclient.NewObjectManager(connector, "Terraform", tenantID)
+
+ obj, err := objMgr.GetNetworkContainerByRef(d.Id())
+ if err != nil {
+ return fmt.Errorf("failed to retrieve network container: %s", err.Error())
+ }
+ d.SetId(obj.Ref)
+
+ return nil
+}
+
+func resourceNetworkContainerUpdate(d *schema.ResourceData, m interface{}) error {
+ nvName := d.Get("network_view_name").(string)
+ cidr := d.Get("cidr").(string)
+ extAttrJSON := d.Get("extensible_attributes").(string)
+ extAttrs := make(map[string]interface{})
+ if extAttrJSON != "" {
+ if err := json.Unmarshal([]byte(extAttrJSON), &extAttrs); err != nil {
+ return fmt.Errorf("cannot process 'extensible_attributes' field: %s", err.Error())
+ }
+ }
+
+ var tenantID string
+ for attrName, attrValueInf := range extAttrs {
+ attrValue, _ := attrValueInf.(string)
+ if attrName == "Tenant ID" {
+ tenantID = attrValue
+ break
+ }
+ }
+
+ if cidr == "" || nvName == "" {
+ return fmt.Errorf(
+ "Tenant ID, network view's name and CIDR are required to update a network container")
+ }
+
+ connector := m.(ibclient.IBConnector)
+ objMgr := ibclient.NewObjectManager(connector, "Terraform", tenantID)
+
+ comment := ""
+ commentText, commentFieldFound := d.GetOk("comment")
+ if commentFieldFound {
+ comment = commentText.(string)
+ }
+
+ nc, err := objMgr.UpdateNetworkContainer(d.Id(), extAttrs, comment)
+ if err != nil {
+ return fmt.Errorf(
+ "failed to update the network container in network view '%s': %s",
+ nvName, err.Error())
+ }
+
+ d.SetId(nc.Ref)
+
+ nc, err = objMgr.GetNetworkContainerByRef(d.Id())
+ if err != nil {
+ return fmt.Errorf("failed to read the network container: %s", err.Error())
+ }
+
+ easBytes, err := json.Marshal(nc.Ea)
+ if err != nil {
+ return fmt.Errorf(
+ "failed to read the network container's state after an update operation: %s",
+ err.Error())
+ }
+ d.Set("extensible_attributes", string(easBytes))
+ d.Set("comment", nc.Comment)
+
+ return nil
+}
+
+func resourceNetworkContainerDelete(d *schema.ResourceData, m interface{}) error {
+ extAttrJSON := d.Get("extensible_attributes").(string)
+ extAttrs := make(map[string]interface{})
+ if extAttrJSON != "" {
+ if err := json.Unmarshal([]byte(extAttrJSON), &extAttrs); err != nil {
+ return fmt.Errorf("cannot process 'extensible_attributes' field: %s", err.Error())
+ }
+ }
+ var tenantID string
+ for attrName, attrValueInf := range extAttrs {
+ attrValue, _ := attrValueInf.(string)
+ if attrName == "Tenant ID" {
+ tenantID = attrValue
+ break
+ }
+ }
+ connector := m.(ibclient.IBConnector)
+ objMgr := ibclient.NewObjectManager(connector, "Terraform", tenantID)
+
+ if _, err := objMgr.DeleteNetworkContainer(d.Id()); err != nil {
+ return fmt.Errorf(
+ "deletion of the network container failed: %s", err.Error())
+ }
+
+ return nil
+}
+
+// TODO: implement this after infoblox-go-client refactoring
+//func resourceNetworkContainerExists(d *schema.ResourceData, m interface{}, isIPv6 bool) (bool, error) {
+// return false, nil
+//}
+
+func resourceIPv4NetworkContainerCreate(d *schema.ResourceData, m interface{}) error {
+ return resourceNetworkContainerCreate(d, m, false)
+}
+
+func resourceIPv4NetworkContainerRead(d *schema.ResourceData, m interface{}) error {
+ return resourceNetworkContainerRead(d, m)
+}
+
+func resourceIPv4NetworkContainerUpdate(d *schema.ResourceData, m interface{}) error {
+ return resourceNetworkContainerUpdate(d, m)
+}
+
+func resourceIPv4NetworkContainerDelete(d *schema.ResourceData, m interface{}) error {
+ return resourceNetworkContainerDelete(d, m)
+}
+
+//func resourceIPv4NetworkContainerExists(d *schema.ResourceData, m interface{}) (bool, error) {
+// return resourceNetworkContainerExists(d, m, false)
+//}
+
+func resourceIPv4NetworkContainer() *schema.Resource {
+ nc := resourceNetworkContainer()
+ nc.Create = resourceIPv4NetworkContainerCreate
+ nc.Read = resourceIPv4NetworkContainerRead
+ nc.Update = resourceIPv4NetworkContainerUpdate
+ nc.Delete = resourceIPv4NetworkContainerDelete
+ //nc.Exists = resourceIPv4NetworkContainerExists
+
+ return nc
+}
+
+func resourceIPv6NetworkContainerCreate(d *schema.ResourceData, m interface{}) error {
+ return resourceNetworkContainerCreate(d, m, true)
+}
+
+func resourceIPv6NetworkContainerRead(d *schema.ResourceData, m interface{}) error {
+ return resourceNetworkContainerRead(d, m)
+}
+
+func resourceIPv6NetworkContainerUpdate(d *schema.ResourceData, m interface{}) error {
+ return resourceNetworkContainerUpdate(d, m)
+}
+
+func resourceIPv6NetworkContainerDelete(d *schema.ResourceData, m interface{}) error {
+ return resourceNetworkContainerDelete(d, m)
+}
+
+//func resourceIPv6NetworkContainerExists(d *schema.ResourceData, m interface{}) (bool, error) {
+// return resourceNetworkContainerExists(d, m, true)
+//}
+
+func resourceIPv6NetworkContainer() *schema.Resource {
+ nc := resourceNetworkContainer()
+ nc.Create = resourceIPv6NetworkContainerCreate
+ nc.Read = resourceIPv6NetworkContainerRead
+ nc.Update = resourceIPv6NetworkContainerUpdate
+ nc.Delete = resourceIPv6NetworkContainerDelete
+ //nc.Exists = resourceIPv6NetworkContainerExists
+
+ return nc
+}
diff --git a/infoblox/resource_infoblox_network_container_test.go b/infoblox/resource_infoblox_network_container_test.go
new file mode 100644
index 000000000..3b6ba8257
--- /dev/null
+++ b/infoblox/resource_infoblox_network_container_test.go
@@ -0,0 +1,276 @@
+package infoblox
+
+import (
+ "fmt"
+ "testing"
+
+ "github.com/hashicorp/terraform/helper/resource"
+ "github.com/hashicorp/terraform/terraform"
+
+ ibclient "github.com/infobloxopen/infoblox-go-client"
+)
+
+const testNetView = "default"
+
+var resCfgNetworkContainer_create_ipv4 = fmt.Sprintf(`
+resource "infoblox_ipv4_network_container" "nc_1" {
+ network_view_name = "%s"
+ cidr = "10.0.0.0/16"
+ comment = "10.0.0.0/16 network container"
+ extensible_attributes = jsonencode({
+ "Tenant ID" = "terraform_test_tenant"
+ Location = "Test loc."
+ Site = "Test site"
+ TestEA1 = ["text1","text2"]
+ TestEA2 = [4,5]
+ })
+}`, testNetView)
+
+var resCfgNetworkContainer_update_ipv4 = fmt.Sprintf(`
+resource "infoblox_ipv4_network_container" "nc_1" {
+ network_view_name = "%s"
+ cidr = "10.0.0.0/16"
+ comment = "new 10.0.0.0/16 network container"
+ extensible_attributes = jsonencode({
+ "Tenant ID" = "terraform_test_tenant"
+ Location = "Test loc. 2"
+ TestEA1 = "text3"
+ TestEA2 = 7
+ })
+}`, testNetView)
+
+var resCfgNetworkContainer_update2_ipv4 = fmt.Sprintf(`
+resource "infoblox_ipv4_network_container" "nc_1" {
+ network_view_name = "%s"
+ cidr = "10.0.0.0/16"
+ comment = ""
+ extensible_attributes = jsonencode({
+ "Tenant ID" = "terraform_test_tenant"
+ })
+}`, testNetView)
+
+var resCfgNetworkContainer_create_ipv6 = fmt.Sprintf(`
+resource "infoblox_ipv6_network_container" "nc_1" {
+ network_view_name = "%s"
+ cidr = "fc00::/56"
+ comment = "fc00::/56 network container"
+ extensible_attributes = jsonencode({
+ "Tenant ID" = "terraform_test_tenant"
+ Location = "Test loc."
+ Site = "Test site"
+ TestEA1 = ["text1","text2"]
+ TestEA2 = [4,5]
+ })
+}`, testNetView)
+
+var resCfgNetworkContainer_update_ipv6 = fmt.Sprintf(`
+resource "infoblox_ipv6_network_container" "nc_1" {
+ network_view_name = "%s"
+ cidr = "fc00::/56"
+ comment = "new comment for fc00::/56 network container"
+ extensible_attributes = jsonencode({
+ "Tenant ID" = "terraform_test_tenant"
+ Location = "Test loc. 2"
+ TestEA1 = ["text3"]
+ TestEA2 = 7
+ })
+}`, testNetView)
+
+func validateNetworkContainer(
+ resourceName string,
+ expectedValue *ibclient.NetworkContainer) resource.TestCheckFunc {
+ return func(s *terraform.State) error {
+ res, found := s.RootModule().Resources[resourceName]
+ if !found {
+ return fmt.Errorf("not found: %s", resourceName)
+ }
+
+ id := res.Primary.ID
+ if id == "" {
+ return fmt.Errorf("ID is not set")
+ }
+
+ connector := testAccProvider.Meta().(ibclient.IBConnector)
+ objMgr := ibclient.NewObjectManager(
+ connector,
+ "terraform_test",
+ "terraform_test_tenant")
+
+ nc, err := objMgr.GetNetworkContainerByRef(id)
+ if err != nil {
+ if isNotFoundError(err) {
+ if expectedValue == nil {
+ return nil
+ }
+ return fmt.Errorf("object with ID '%s' not found, but expected to exist", id)
+ }
+ }
+
+ expNv := expectedValue.NetviewName
+ if nc.NetviewName != expNv {
+ return fmt.Errorf(
+ "the value of 'network_view_name' field is '%s', but expected '%s'",
+ nc.NetviewName, expNv)
+ }
+
+ expComment := expectedValue.Comment
+ if nc.Comment != expComment {
+ return fmt.Errorf(
+ "the value of 'comment' field is '%s', but expected '%s'",
+ nc.Comment, expComment)
+ }
+
+ expCidr := expectedValue.Cidr
+ if nc.Cidr != expCidr {
+ return fmt.Errorf(
+ "the value of 'cidr' field is '%s', but expected '%s'",
+ nc.Cidr, expCidr)
+ }
+
+ // the rest is about extensible attributes
+ expectedEAs := expectedValue.Ea
+ if expectedEAs == nil && nc.Ea != nil {
+ return fmt.Errorf(
+ "the object with ID '%s' has 'extensible_attributes' field, but it is not expected to exist", id)
+ }
+ if expectedEAs != nil && nc.Ea == nil {
+ return fmt.Errorf(
+ "the object with ID '%s' has no 'extensible_attributes' field, but it is expected to exist", id)
+ }
+ if expectedEAs == nil {
+ return nil
+ }
+
+ return validateEAs(nc.Ea, expectedEAs)
+ }
+}
+
+func TestAcc_resourceNetworkContainer_ipv4(t *testing.T) {
+ resource.Test(t, resource.TestCase{
+ PreCheck: func() { testAccPreCheck(t) },
+ Providers: testAccProviders,
+ CheckDestroy: testAccCheckNetworkContainerDestroy,
+ Steps: []resource.TestStep{
+ {
+ Config: resCfgNetworkContainer_create_ipv4,
+ Check: validateNetworkContainer(
+ "infoblox_ipv4_network_container.nc_1",
+ &ibclient.NetworkContainer{
+ NetviewName: testNetView,
+ Cidr: "10.0.0.0/16",
+ Comment: "10.0.0.0/16 network container",
+ Ea: ibclient.EA{
+ "Tenant ID": "terraform_test_tenant",
+ "Location": "Test loc.",
+ "Site": "Test site",
+ "TestEA1": []string{"text1", "text2"},
+ "TestEA2": []int{4, 5},
+ },
+ },
+ ),
+ },
+ {
+ Config: resCfgNetworkContainer_update_ipv4,
+ Check: validateNetworkContainer(
+ "infoblox_ipv4_network_container.nc_1",
+ &ibclient.NetworkContainer{
+ NetviewName: testNetView,
+ Cidr: "10.0.0.0/16",
+ Comment: "new 10.0.0.0/16 network container",
+ Ea: ibclient.EA{
+ "Tenant ID": "terraform_test_tenant",
+ "Location": "Test loc. 2",
+
+ // lists which contain ony one element are reduced by NIOS to a single-value element
+ "TestEA1": "text3",
+ "TestEA2": 7,
+ },
+ },
+ ),
+ },
+ {
+ Config: resCfgNetworkContainer_update2_ipv4,
+ Check: validateNetworkContainer(
+ "infoblox_ipv4_network_container.nc_1",
+ &ibclient.NetworkContainer{
+ NetviewName: testNetView,
+ Cidr: "10.0.0.0/16",
+ Comment: "",
+ Ea: ibclient.EA{},
+ },
+ ),
+ },
+ },
+ })
+}
+
+func TestAcc_resourceNetworkContainer_ipv6(t *testing.T) {
+ resource.Test(t, resource.TestCase{
+ PreCheck: func() { testAccPreCheck(t) },
+ Providers: testAccProviders,
+ CheckDestroy: testAccCheckNetworkContainerDestroy,
+ Steps: []resource.TestStep{
+ {
+ Config: resCfgNetworkContainer_create_ipv6,
+ Check: validateNetworkContainer(
+ "infoblox_ipv6_network_container.nc_1",
+ &ibclient.NetworkContainer{
+ NetviewName: testNetView,
+ Cidr: "fc00::/56",
+ Comment: "fc00::/56 network container",
+ Ea: ibclient.EA{
+ "Tenant ID": "terraform_test_tenant",
+ "Location": "Test loc.",
+ "Site": "Test site",
+ "TestEA1": []string{"text1", "text2"},
+ "TestEA2": []int{4, 5},
+ },
+ },
+ ),
+ },
+ {
+ Config: resCfgNetworkContainer_update_ipv6,
+ Check: validateNetworkContainer(
+ "infoblox_ipv6_network_container.nc_1",
+ &ibclient.NetworkContainer{
+ NetviewName: testNetView,
+ Cidr: "fc00::/56",
+ Comment: "new comment for fc00::/56 network container",
+ Ea: ibclient.EA{
+ "Tenant ID": "terraform_test_tenant",
+ "Location": "Test loc. 2",
+
+ // lists which contain ony one element are reduced by NIOS to a single-value element
+ "TestEA1": "text3",
+ "TestEA2": 7,
+ },
+ },
+ ),
+ },
+ },
+ })
+}
+
+func testAccCheckNetworkContainerDestroy(s *terraform.State) error {
+ connector := testAccProvider.Meta().(ibclient.IBConnector)
+ objMgr := ibclient.NewObjectManager(
+ connector,
+ "terraform_test",
+ "terraform_test_tenant")
+ for _, rs := range s.RootModule().Resources {
+ if rs.Type != "infoblox_ipv4_network_container" && rs.Type != "infoblox_ipv6_network_container" {
+ continue
+ }
+ res, err := objMgr.GetNetworkContainerByRef(rs.Primary.ID)
+ if err != nil {
+ if isNotFoundError(err) {
+ continue
+ }
+ return err
+ }
+ if res != nil {
+ return fmt.Errorf("object with ID '%s' remains", rs.Primary.ID)
+ }
+ }
+ return nil
+}
diff --git a/infoblox/resource_infoblox_network_test.go b/infoblox/resource_infoblox_network_test.go
index ace7f96d1..1444c112c 100644
--- a/infoblox/resource_infoblox_network_test.go
+++ b/infoblox/resource_infoblox_network_test.go
@@ -2,7 +2,6 @@ package infoblox
import (
"fmt"
- "regexp"
"testing"
"github.com/hashicorp/terraform/helper/resource"
@@ -10,143 +9,238 @@ import (
ibclient "github.com/infobloxopen/infoblox-go-client"
)
-func TestAccresourceNetwork(t *testing.T) {
+var testAccresourceIPv4NetworkCreate = fmt.Sprintf(`
+resource "infoblox_ipv4_network" "foo"{
+ network_view_name="default"
+ cidr="10.10.0.0/24"
+ comment = "10.0.0.0/24 network created"
+ extensible_attributes = jsonencode({
+ "Network Name"= "demo-network"
+ "Tenant ID" = "terraform_test_tenant"
+ Location = "Test loc."
+ Site = "Test site"
+ TestEA1 = ["text1","text2"]
+ TestEA2 = [4,5]
+ })
+ }`)
+
+var testAccresourceIPv4NetworkUpdate = fmt.Sprintf(`
+resource "infoblox_ipv4_network" "foo"{
+ network_view_name="default"
+ cidr="10.10.0.0/24"
+ comment = "10.0.0.0/24 network updated"
+ extensible_attributes = jsonencode({
+ "Network Name"= "demo-network"
+ "Tenant ID" = "terraform_test_tenant"
+ Location = "Test loc. 2"
+ Site = "Test site"
+ TestEA1 = "text3"
+ TestEA2 = 7
+ })
+ }`)
+
+var testAccresourceIPv6NetworkCreate = fmt.Sprintf(`
+ resource "infoblox_ipv6_network" "foo"{
+ network_view_name="default"
+ cidr="2001:db8:abcd:12::/64"
+ comment = "2001:db8:abcd:12::/64 network created"
+ extensible_attributes = jsonencode({
+ "Tenant ID" = "terraform_test_tenant"
+ "Network Name"= "demo-network"
+ Location = "Test loc."
+ Site = "Test site"
+ TestEA1 = ["text1","text2"]
+ TestEA2 = [4,5]
+ })
+ }`)
+
+var testAccresourceIPv6NetworkUpdate = fmt.Sprintf(`
+ resource "infoblox_ipv6_network" "foo"{
+ network_view_name="default"
+ cidr="2001:db8:abcd:12::/64"
+ comment = "2001:db8:abcd:12::/64 network updated"
+ extensible_attributes = jsonencode({
+ "Tenant ID" = "terraform_test_tenant"
+ "Network Name"= "demo-network"
+ Location = "Test loc. 2"
+ Site = "Test site"
+ TestEA1 = ["text3"]
+ TestEA2 = 7
+ })
+ }`)
+
+func validateNetwork(
+ resourceName string,
+ expectedValue *ibclient.Network) resource.TestCheckFunc {
+ return func(s *terraform.State) error {
+ res, found := s.RootModule().Resources[resourceName]
+ if !found {
+ return fmt.Errorf("not found: %s", resourceName)
+ }
+
+ id := res.Primary.ID
+ if id == "" {
+ return fmt.Errorf("ID is not set")
+ }
+
+ connector := testAccProvider.Meta().(ibclient.IBConnector)
+ objMgr := ibclient.NewObjectManager(
+ connector,
+ "terraform_test",
+ "terraform_test_tenant")
+ nw, err := objMgr.GetNetworkByRef(id)
+ if err != nil {
+ if isNotFoundError(err) {
+ if expectedValue == nil {
+ return nil
+ }
+ return fmt.Errorf("object with ID '%s' not found, but expected to exist", id)
+ }
+ }
+ expNv := expectedValue.NetviewName
+ if nw.NetviewName != expNv {
+ return fmt.Errorf(
+ "the value of 'network_view_name' field is '%s', but expected '%s'",
+ nw.NetviewName, expNv)
+ }
+
+ expComment := expectedValue.Comment
+ if nw.Comment != expComment {
+ return fmt.Errorf(
+ "the value of 'comment' field is '%s', but expected '%s'",
+ nw.Comment, expComment)
+ }
+ // the rest is about extensible attributes
+ expectedEAs := expectedValue.Ea
+ if expectedEAs == nil && nw.Ea != nil {
+ return fmt.Errorf(
+ "the object with ID '%s' has 'extensible_attributes' field, but it is not expected to exist", id)
+ }
+ if expectedEAs != nil && nw.Ea == nil {
+ return fmt.Errorf(
+ "the object with ID '%s' has no 'extensible_attributes' field, but it is expected to exist", id)
+ }
+ if expectedEAs == nil {
+ return nil
+ }
+
+ return validateEAs(nw.Ea, expectedEAs)
+ }
+}
+
+func testAccCheckNetworkDestroy(s *terraform.State) error {
+ connector := testAccProvider.Meta().(ibclient.IBConnector)
+ objMgr := ibclient.NewObjectManager(
+ connector,
+ "terraform_test",
+ "terraform_test_tenant")
+ for _, rs := range s.RootModule().Resources {
+ if rs.Type != "infoblox_network" && rs.Type != "infoblox_ipv6_network" {
+ continue
+ }
+ res, err := objMgr.GetNetworkByRef(rs.Primary.ID)
+ if err != nil {
+ if isNotFoundError(err) {
+ continue
+ }
+ return err
+ }
+ if res != nil {
+ return fmt.Errorf("object with ID '%s' remains", rs.Primary.ID)
+ }
+ }
+ return nil
+}
+
+func TestAcc_resourceNetwork_ipv4(t *testing.T) {
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckNetworkDestroy,
Steps: []resource.TestStep{
- resource.TestStep{
- Config: testAccresourceNetworkCreate,
- Check: resource.ComposeTestCheckFunc(
- testAccCreateNetworkExists(t, "infoblox_network.foo", "10.10.0.0/24", "default", "demo-network"),
+ {
+ Config: testAccresourceIPv4NetworkCreate,
+ Check: validateNetwork(
+ "infoblox_ipv4_network.foo",
+ &ibclient.Network{
+ Cidr: "10.0.0.0/24",
+ Comment: "10.0.0.0/24 network created",
+ Ea: ibclient.EA{
+ "Network Name": "demo-network",
+ "Tenant ID": "terraform_test_tenant",
+ "Location": "Test loc.",
+ "Site": "Test site",
+ "TestEA1": []string{"text1", "text2"},
+ "TestEA2": []int{4, 5},
+ },
+ },
),
},
- resource.TestStep{
- Config: testAccresourceNetworkUpdate,
- Check: resource.ComposeTestCheckFunc(
- testAccCreateNetworkExists(t, "infoblox_network.foo", "10.10.0.0/24", "default", "demo-network"),
+ {
+ Config: testAccresourceIPv4NetworkUpdate,
+ Check: validateNetwork(
+ "infoblox_ipv4_network.foo",
+ &ibclient.Network{
+ Cidr: "10.0.0.0/24",
+ Comment: "10.0.0.0/24 network updated",
+ Ea: ibclient.EA{
+ "Network Name": "demo-network",
+ "Tenant ID": "terraform_test_tenant",
+ "Location": "Test loc. 2",
+ // lists which contain ony one element are reduced by NIOS to a single-value element
+ "TestEA1": "text3",
+ "TestEA2": 7,
+ },
+ },
),
},
},
})
}
-func TestAccresourceNetwork_Allocate(t *testing.T) {
-
+func TestAcc_resourceNetwork_ipv6(t *testing.T) {
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckNetworkDestroy,
Steps: []resource.TestStep{
- resource.TestStep{
- Config: testAccresourceNetworkAllocate,
- Check: resource.ComposeTestCheckFunc(
- testAccCreateNetworkExists(t, "infoblox_network.foo0", "10.0.0.0/24", "default", "demo-network"),
- testAccCreateNetworkExists(t, "infoblox_network.foo1", "10.0.1.0/24", "default", "demo-network"),
+ {
+ Config: testAccresourceIPv6NetworkCreate,
+ Check: validateNetwork(
+ "infoblox_ipv6_network.foo",
+ &ibclient.Network{
+ Cidr: "2001:db8:abcd:12::/64",
+ Comment: "2001:db8:abcd:12::/64 network created",
+ Ea: ibclient.EA{
+ "Network Name": "demo-network",
+ "Tenant ID": "terraform_test_tenant",
+ "Location": "Test loc.",
+ "Site": "Test site",
+ "TestEA1": []string{"text1", "text2"},
+ "TestEA2": []int{4, 5},
+ },
+ },
),
},
- },
- })
-}
-
-func TestAccresourceNetwork_Allocate_Fail(t *testing.T) {
-
- resource.Test(t, resource.TestCase{
- PreCheck: func() { testAccPreCheck(t) },
- Providers: testAccProviders,
- CheckDestroy: testAccCheckNetworkDestroy,
- Steps: []resource.TestStep{
- resource.TestStep{
- Config: testAccresourceNetworkAllocateFail,
- ExpectError: regexp.MustCompile(`Allocation of network block failed in network view \(default\) : Parent network container 11.11.0.0/16 not found.`),
+ {
+ Config: testAccresourceIPv6NetworkUpdate,
+ Check: validateNetwork(
+ "infoblox_ipv6_network.foo",
+ &ibclient.Network{
+ Cidr: "2001:db8:abcd:12::/64",
+ Comment: "2001:db8:abcd:12::/64 network updated",
+ Ea: ibclient.EA{
+ "Network Name": "demo-network",
+ "Tenant ID": "terraform_test_tenant",
+ "Location": "Test loc. 2",
+ // lists which contain ony one element are reduced by NIOS to a single-value element
+ "TestEA1": "text3",
+ "TestEA2": 7,
+ },
+ },
+ ),
},
},
})
}
-
-func testAccCheckNetworkDestroy(s *terraform.State) error {
- meta := testAccProvider.Meta()
- for _, rs := range s.RootModule().Resources {
- if rs.Type != "infoblox_network" {
- continue
- }
- Connector := meta.(*ibclient.Connector)
- objMgr := ibclient.NewObjectManager(Connector, "terraform_test", "test")
- networkName, _ := objMgr.GetNetwork("demo-network", "10.10.0.0/24", nil)
- if networkName != nil {
- return fmt.Errorf("Network not found")
- }
-
- }
- return nil
-}
-
-func testAccCreateNetworkExists(t *testing.T, n string, cidr string, networkViewName string, networkName string) resource.TestCheckFunc {
- return func(s *terraform.State) error {
- rs, ok := s.RootModule().Resources[n]
- if !ok {
- return fmt.Errorf("Not found:%s", n)
- }
- if rs.Primary.ID == "" {
- return fmt.Errorf("No ID i set")
- }
- meta := testAccProvider.Meta()
- Connector := meta.(*ibclient.Connector)
- objMgr := ibclient.NewObjectManager(Connector, "terraform_test", "test")
-
- networkName, _ := objMgr.GetNetwork(networkName, cidr, nil)
- if networkName != nil {
- return fmt.Errorf("Network not found")
- }
- return nil
- }
-}
-
-var testAccresourceNetworkCreate = fmt.Sprintf(`
-resource "infoblox_network" "foo"{
- network_view_name="default"
- network_name="demo-network"
- cidr="10.10.0.0/24"
- tenant_id="foo"
- }`)
-
-/*
-Right now no infoblox_network_container resource available
-So, before run acceptance test TestAccresourceNetwork_Allocate
-in default network view should be created network container 10.0.0.0/16
-*/
-var testAccresourceNetworkAllocate = fmt.Sprintf(`
-resource "infoblox_network" "foo0"{
- network_view_name="default"
- network_name="demo-network"
- tenant_id="foo"
- allocate_prefix_len=24
- parent_cidr="10.0.0.0/16"
- }
-resource "infoblox_network" "foo1"{
- network_view_name="default"
- network_name="demo-network"
- tenant_id="foo"
- allocate_prefix_len=24
- parent_cidr="10.0.0.0/16"
- }`)
-
-/* Network container 11.11.0.0 should NOT exists to pass this test */
-var testAccresourceNetworkAllocateFail = fmt.Sprintf(`
-resource "infoblox_network" "foo0"{
- network_view_name="default"
- network_name="demo-network"
- tenant_id="foo"
- allocate_prefix_len=24
- parent_cidr="11.11.0.0/16"
- }`)
-
-var testAccresourceNetworkUpdate = fmt.Sprintf(`
-resource "infoblox_network" "foo"{
- network_view_name="default"
- network_name="demo-network"
- cidr="10.10.0.0/24"
- tenant_id="foo"
- }`)
diff --git a/infoblox/resource_infoblox_network_view.go b/infoblox/resource_infoblox_network_view.go
index 418daec43..b9fb03570 100644
--- a/infoblox/resource_infoblox_network_view.go
+++ b/infoblox/resource_infoblox_network_view.go
@@ -2,9 +2,9 @@ package infoblox
import (
"fmt"
+
"github.com/hashicorp/terraform/helper/schema"
- "github.com/infobloxopen/infoblox-go-client"
- "log"
+ ibclient "github.com/infobloxopen/infoblox-go-client"
)
func resourceNetworkView() *schema.Resource {
@@ -15,94 +15,178 @@ func resourceNetworkView() *schema.Resource {
Delete: resourceNetworkViewDelete,
Schema: map[string]*schema.Schema{
- "network_view_name": &schema.Schema{
+ "network_view_name": {
Type: schema.TypeString,
Required: true,
Description: "Desired name of the view shown in NIOS appliance.",
},
- "network_view_ref": &schema.Schema{
- Type: schema.TypeString,
- Computed: true,
- },
- "tenant_id": &schema.Schema{
+ "tenant_id": {
Type: schema.TypeString,
Required: true,
- Description: "Unique identifier of your tenant in cloud.",
+ Description: "ID of a tenant to be used when creating objects.",
},
+
+ // TODO: uncomment this once EA and comment support is added for NetView in go-client
+ //"comment": {
+ // Type: schema.TypeString,
+ // Default: "",
+ // Optional: true,
+ // Description: "A description of the IP allocation.",
+ //},
+ //"extensible_attributes": {
+ // Type: schema.TypeString,
+ // Default: "",
+ // Optional: true,
+ // Description: "The Extensible attributes of the network container to be added/updated, as a map in JSON format",
+ //},
},
}
}
func resourceNetworkViewCreate(d *schema.ResourceData, m interface{}) error {
- log.Printf("[DEBUG] %s: Beginning network view Creation", resourceNetworkViewIDString(d))
+ var tenantID string
- tenantID := d.Get("tenant_id").(string)
- Connector := m.(*ibclient.Connector)
- objMgr := ibclient.NewObjectManager(Connector, "Terraform", tenantID)
+ networkViewName := d.Get("network_view_name").(string)
- networkViewName, err := objMgr.CreateNetworkView(d.Get("network_view_name").(string))
- if err != nil {
- return fmt.Errorf("Failed to create Network View : %s", err)
+ // TODO: uncomment this once EA and comment support is added for NetView in go-client
+ //extAttrJSON := d.Get("extensible_attributes").(string)
+ //extAttrs := make(map[string]interface{})
+ //if extAttrJSON != "" {
+ // if err := json.Unmarshal([]byte(extAttrJSON), &extAttrs); err != nil {
+ // return fmt.Errorf("cannot process 'extensible_attributes' field: %s", err.Error())
+ // }
+ //}
+ //for attrName, attrValue := range extAttrs {
+ // if attrName == "Tenant ID" {
+ // tenantID = attrValue.(string)
+ // break
+ // }
+ //}
+
+ tenantIdTfProp, found := d.GetOk("tenant_id")
+ if found {
+ tenantID = tenantIdTfProp.(string)
+ } else {
+ tenantID = defaultTenantId
}
- d.SetId(networkViewName.Name)
+ Connector := m.(ibclient.IBConnector)
+ objMgr := ibclient.NewObjectManager(Connector, "Terraform", tenantID)
- log.Printf("[DEBUG] %s: Completed network view Creation", resourceNetworkViewIDString(d))
+ // TODO: Add comment and EAs while creation
+ // comment := d.Get("comment").(string)
+ //networkView, err := objMgr.CreateNetworkView(networkViewName, comment, extAttrs)
- return resourceNetworkViewRead(d, m)
+ obj, err := objMgr.CreateNetworkView(networkViewName)
+ if err != nil {
+ return fmt.Errorf("Failed to create Network View : %s", err)
+ }
+ d.SetId(obj.Ref)
+ return nil
}
func resourceNetworkViewRead(d *schema.ResourceData, m interface{}) error {
- log.Printf("[DEBUG] %s: Beginning to get network view ", resourceNetworkViewIDString(d))
+ var tenantID string
+
+ // TODO: uncomment this once EA and comment support is added for NetView in go-client
+ //extAttrJSON := d.Get("extensible_attributes").(string)
+ //extAttrs := make(map[string]interface{})
+ //if extAttrJSON != "" {
+ // if err := json.Unmarshal([]byte(extAttrJSON), &extAttrs); err != nil {
+ // return fmt.Errorf("cannot process 'extensible_attributes' field: %s", err.Error())
+ // }
+ //}
+ //for attrName, attrValue := range extAttrs {
+ // if attrName == "Tenant ID" {
+ // tenantID = attrValue.(string)
+ // break
+ // }
+ //}
+
+ tenantIdTfProp, found := d.GetOk("tenant_id")
+ if found {
+ tenantID = tenantIdTfProp.(string)
+ } else {
+ tenantID = defaultTenantId
+ }
- tenantID := d.Get("tenant_id").(string)
- Connector := m.(*ibclient.Connector)
+ Connector := m.(ibclient.IBConnector)
objMgr := ibclient.NewObjectManager(Connector, "Terraform", tenantID)
- obj, err := objMgr.GetNetworkView(d.Id())
+ obj, err := objMgr.GetNetworkViewByRef(d.Id())
if err != nil {
- return fmt.Errorf("Failed to get Network View : %s", err)
+ return fmt.Errorf("Failed to get Network View : %s", err.Error())
}
- d.SetId(obj.Name)
- d.Set("network_view_ref", obj.Ref)
-
- log.Printf("[DEBUG] %s: got Network View", resourceNetworkViewIDString(d))
+ d.SetId(obj.Ref)
return nil
}
func resourceNetworkViewUpdate(d *schema.ResourceData, m interface{}) error {
+ // TODO: Implement update at go client
+ /*
+ networkViewName := d.Get("network_view_name").(string)
+ comment := d.Get("comment").(string)
+ extAttrJSON := d.Get("extensible_attributes").(string)
+ extAttrs := make(map[string]interface{})
+ if extAttrJSON != "" {
+ if err := json.Unmarshal([]byte(extAttrJSON), &extAttrs); err != nil {
+ return fmt.Errorf("cannot process 'extensible_attributes' field: %s", err.Error())
+ }
+ }
+ var tenantID string
+ for attrName, attrValue := range extAttrs {
+ if attrName == "Tenant ID" {
+ tenantID = attrValue.(string)
+ break
+ }
+ }
+ Connector := m.(*ibclient.Connector)
+ objMgr := ibclient.NewObjectManager(Connector, "Terraform", tenantID)
+ obj, err := objMgr.UpdateNetworkView(networkViewName, comment, extAttrs)
+ if err != nil {
+ return fmt.Errorf("Failed to update Network View : %s", err.Error())
+ }
+ d.SetId(obj.Ref)
+ return nil
+ */
return fmt.Errorf("network view updation is not supported")
}
func resourceNetworkViewDelete(d *schema.ResourceData, m interface{}) error {
- log.Printf("[DEBUG] %s: Beginning Deletion of network block", resourceNetworkIDString(d))
+ var tenantID string
networkViewName := d.Get("network_view_name").(string)
- networkViewRef := d.Get("network_view_ref").(string)
- tenantID := d.Get("tenant_id").(string)
- connector := m.(*ibclient.Connector)
+ // TODO: uncomment this once EA and comment support is added for NetView in go-client
+ //extAttrJSON := d.Get("extensible_attributes").(string)
+ //extAttrs := make(map[string]interface{})
+ //if extAttrJSON != "" {
+ // if err := json.Unmarshal([]byte(extAttrJSON), &extAttrs); err != nil {
+ // return fmt.Errorf("cannot process 'extensible_attributes' field: %s", err.Error())
+ // }
+ //}
+ //for attrName, attrValue := range extAttrs {
+ // if attrName == "Tenant ID" {
+ // tenantID = attrValue.(string)
+ // break
+ // }
+ //}
+
+ tenantIdTfProp, found := d.GetOk("tenant_id")
+ if found {
+ tenantID = tenantIdTfProp.(string)
+ } else {
+ tenantID = defaultTenantId
+ }
+
+ connector := m.(ibclient.IBConnector)
objMgr := ibclient.NewObjectManager(connector, "Terraform", tenantID)
- _, err := objMgr.DeleteNetworkView(networkViewRef)
+ _, err := objMgr.DeleteNetworkView(d.Id())
if err != nil {
- return fmt.Errorf("Deletion of Network view (%s) failed: %s", networkViewName, err)
+ return fmt.Errorf("Deletion of Network view %s failed: %s", networkViewName, err.Error())
}
- d.SetId("")
- log.Printf("[DEBUG] %s: Deletion of network block complete", resourceNetworkViewIDString(d))
return nil
}
-
-type resourceNetworkViewIDStringInterface interface {
- Id() string
-}
-
-func resourceNetworkViewIDString(d resourceNetworkViewIDStringInterface) string {
- id := d.Id()
- if id == "" {
- id = ""
- }
- return fmt.Sprintf("infoblox_network_view(ID = %s)", id)
-}
diff --git a/infoblox/resource_infoblox_network_view_test.go b/infoblox/resource_infoblox_network_view_test.go
index e70a1c7b3..819a3c976 100644
--- a/infoblox/resource_infoblox_network_view_test.go
+++ b/infoblox/resource_infoblox_network_view_test.go
@@ -9,9 +9,9 @@ import (
)
var testAccresourceNetworkView = fmt.Sprintf(`
-resource "infoblox_network_view" "foo"{
- network_view_name="test1"
- tenant_id="foo"
+ resource "infoblox_network_view" "foo"{
+ network_view_name="test1"
+ tenant_id="foo"
}`)
func TestAccresourceNetworkView(t *testing.T) {
diff --git a/vendor/github.com/infobloxopen/infoblox-go-client/connector.go b/vendor/github.com/infobloxopen/infoblox-go-client/connector.go
index df10dfb8b..b24d30d61 100644
--- a/vendor/github.com/infobloxopen/infoblox-go-client/connector.go
+++ b/vendor/github.com/infobloxopen/infoblox-go-client/connector.go
@@ -62,9 +62,9 @@ func NewTransportConfig(sslVerify string, httpRequestTimeout int, httpPoolConnec
type HttpRequestBuilder interface {
Init(HostConfig)
- BuildUrl(r RequestType, objType string, ref string, returnFields []string, queryParams QueryParams) (urlStr string)
+ BuildUrl(r RequestType, objType string, ref string, returnFields []string, queryParams *QueryParams) (urlStr string)
BuildBody(r RequestType, obj IBObject) (jsonStr []byte)
- BuildRequest(r RequestType, obj IBObject, ref string, queryParams QueryParams) (req *http.Request, err error)
+ BuildRequest(r RequestType, obj IBObject, ref string, queryParams *QueryParams) (req *http.Request, err error)
}
type HttpRequestor interface {
@@ -82,7 +82,7 @@ type WapiHttpRequestor struct {
type IBConnector interface {
CreateObject(obj IBObject) (ref string, err error)
- GetObject(obj IBObject, ref string, res interface{}) error
+ GetObject(obj IBObject, ref string, queryParams *QueryParams, res interface{}) error
DeleteObject(ref string) (refRes string, err error)
UpdateObject(obj IBObject, ref string) (refRes string, err error)
}
@@ -129,8 +129,8 @@ func getHTTPResponseError(resp *http.Response) error {
func (whr *WapiHttpRequestor) Init(cfg TransportConfig) {
tr := &http.Transport{
TLSClientConfig: &tls.Config{InsecureSkipVerify: !cfg.SslVerify,
- RootCAs: cfg.certPool,
- Renegotiation: tls.RenegotiateOnceAsClient},
+ RootCAs: cfg.certPool,
+ Renegotiation: tls.RenegotiateOnceAsClient},
MaxIdleConnsPerHost: cfg.HttpPoolConnections,
}
@@ -168,7 +168,7 @@ func (wrb *WapiRequestBuilder) Init(cfg HostConfig) {
wrb.HostConfig = cfg
}
-func (wrb *WapiRequestBuilder) BuildUrl(t RequestType, objType string, ref string, returnFields []string, queryParams QueryParams) (urlStr string) {
+func (wrb *WapiRequestBuilder) BuildUrl(t RequestType, objType string, ref string, returnFields []string, queryParams *QueryParams) (urlStr string) {
path := []string{"wapi", "v" + wrb.HostConfig.Version}
if len(ref) > 0 {
path = append(path, ref)
@@ -186,6 +186,10 @@ func (wrb *WapiRequestBuilder) BuildUrl(t RequestType, objType string, ref strin
if queryParams.forceProxy {
vals.Set("_proxy_search", "GM")
}
+ for k, v := range queryParams.searchFields {
+ vals.Set(k, v)
+ }
+
qry = vals.Encode()
}
@@ -222,7 +226,7 @@ func (wrb *WapiRequestBuilder) BuildBody(t RequestType, obj IBObject) []byte {
return objJSON
}
-func (wrb *WapiRequestBuilder) BuildRequest(t RequestType, obj IBObject, ref string, queryParams QueryParams) (req *http.Request, err error) {
+func (wrb *WapiRequestBuilder) BuildRequest(t RequestType, obj IBObject, ref string, queryParams *QueryParams) (req *http.Request, err error) {
var (
objType string
returnFields []string
@@ -234,7 +238,7 @@ func (wrb *WapiRequestBuilder) BuildRequest(t RequestType, obj IBObject, ref str
urlStr := wrb.BuildUrl(t, objType, ref, returnFields, queryParams)
var bodyStr []byte
- if obj != nil {
+ if obj != nil && (t == CREATE || t == UPDATE) {
bodyStr = wrb.BuildBody(t, obj)
}
@@ -249,7 +253,7 @@ func (wrb *WapiRequestBuilder) BuildRequest(t RequestType, obj IBObject, ref str
return
}
-func (c *Connector) makeRequest(t RequestType, obj IBObject, ref string, queryParams QueryParams) (res []byte, err error) {
+func (c *Connector) makeRequest(t RequestType, obj IBObject, ref string, queryParams *QueryParams) (res []byte, err error) {
var req *http.Request
req, err = c.RequestBuilder.BuildRequest(t, obj, ref, queryParams)
res, err = c.Requestor.SendRequest(req)
@@ -265,7 +269,7 @@ func (c *Connector) makeRequest(t RequestType, obj IBObject, ref string, queryPa
func (c *Connector) CreateObject(obj IBObject) (ref string, err error) {
ref = ""
- queryParams := QueryParams{forceProxy: false}
+ queryParams := NewQueryParams(false, nil)
resp, err := c.makeRequest(CREATE, obj, "", queryParams)
if err != nil || len(resp) == 0 {
log.Printf("CreateObject request error: '%s'\n", err)
@@ -281,8 +285,11 @@ func (c *Connector) CreateObject(obj IBObject) (ref string, err error) {
return
}
-func (c *Connector) GetObject(obj IBObject, ref string, res interface{}) (err error) {
- queryParams := QueryParams{forceProxy: false}
+// TODO: distinguish between "not found" and other kinds of errors.
+func (c *Connector) GetObject(
+ obj IBObject, ref string,
+ queryParams *QueryParams, res interface{}) (err error) {
+
resp, err := c.makeRequest(GET, obj, ref, queryParams)
//to check empty underlying value of interface
var result interface{}
@@ -312,7 +319,7 @@ func (c *Connector) GetObject(obj IBObject, ref string, res interface{}) (err er
func (c *Connector) DeleteObject(ref string) (refRes string, err error) {
refRes = ""
- queryParams := QueryParams{forceProxy: false}
+ queryParams := NewQueryParams(false, nil)
resp, err := c.makeRequest(DELETE, nil, ref, queryParams)
if err != nil {
log.Printf("DeleteObject request error: '%s'\n", err)
@@ -329,7 +336,7 @@ func (c *Connector) DeleteObject(ref string) (refRes string, err error) {
}
func (c *Connector) UpdateObject(obj IBObject, ref string) (refRes string, err error) {
- queryParams := QueryParams{forceProxy: false}
+ queryParams := NewQueryParams(false, nil)
refRes = ""
resp, err := c.makeRequest(UPDATE, obj, ref, queryParams)
if err != nil {
@@ -349,7 +356,7 @@ func (c *Connector) UpdateObject(obj IBObject, ref string) (refRes string, err e
// be used in a defer statement after the Connector has been successfully
// initialized.
func (c *Connector) Logout() (err error) {
- queryParams := QueryParams{forceProxy: false}
+ queryParams := NewQueryParams(false, nil)
_, err = c.makeRequest(CREATE, nil, "logout", queryParams)
if err != nil {
log.Printf("Logout request error: '%s'\n", err)
@@ -362,12 +369,13 @@ var ValidateConnector = validateConnector
func validateConnector(c *Connector) (err error) {
// GET UserProfile request is used here to validate connector's basic auth and reachability.
- var response []UserProfile
- userprofile := NewUserProfile(UserProfile{})
- err = c.GetObject(userprofile, "", &response)
- if err != nil {
- log.Printf("Failed to connect to the Grid, err: %s \n", err)
- }
+ // TODO: It seems to be broken, needs to be fixed.
+ //var response []UserProfile
+ //userprofile := NewUserProfile(UserProfile{})
+ //err = c.GetObject(userprofile, "", &response)
+ //if err != nil {
+ // log.Printf("Failed to connect to the Grid, err: %s \n", err)
+ //}
return
}
diff --git a/vendor/github.com/infobloxopen/infoblox-go-client/lock.go b/vendor/github.com/infobloxopen/infoblox-go-client/lock.go
index b4d67055c..1881d62b3 100644
--- a/vendor/github.com/infobloxopen/infoblox-go-client/lock.go
+++ b/vendor/github.com/infobloxopen/infoblox-go-client/lock.go
@@ -194,7 +194,8 @@ func (l *NetworkViewLock) Lock() error {
}
if _, ok := nw.Ea[l.LockEA]; !ok {
- err = l.ObjMgr.UpdateNetworkViewEA(nw.Ref, EA{l.LockEA: freeLockVal}, nil)
+ nw.Ea[l.LockEA] = freeLockVal
+ err = l.ObjMgr.UpdateNetworkViewEA(nw.Ref, nw.Ea)
if err != nil {
return fmt.Errorf("Failed to Update Network view with Lock EA")
}
diff --git a/vendor/github.com/infobloxopen/infoblox-go-client/object_manager.go b/vendor/github.com/infobloxopen/infoblox-go-client/object_manager.go
index e6c6611aa..d3a7f82ba 100644
--- a/vendor/github.com/infobloxopen/infoblox-go-client/object_manager.go
+++ b/vendor/github.com/infobloxopen/infoblox-go-client/object_manager.go
@@ -4,59 +4,88 @@ import (
"encoding/json"
"errors"
"fmt"
+ "net"
+ "net/url"
"regexp"
)
type IBObjectManager interface {
- AllocateIP(netview string, cidr string, ipAddr string, macAddress string, name string, ea EA) (*FixedAddress, error)
- AllocateNetwork(netview string, cidr string, prefixLen uint, name string, comment string, ea EA) (network *Network, err error)
+ AllocateIP(netview string, cidr string, ipAddr string, isIPv6 bool, macAddress string, name string, comment string, eas EA) (*FixedAddress, error)
+ AllocateNetwork(netview string, cidr string, isIPv6 bool, prefixLen uint, comment string, eas EA) (network *Network, err error)
CreateARecord(netview string, dnsview string, recordname string, cidr string, ipAddr string, ea EA) (*RecordA, error)
CreateZoneAuth(fqdn string, ea EA) (*ZoneAuth, error)
CreateCNAMERecord(canonical string, recordname string, dnsview string, ea EA) (*RecordCNAME, error)
CreateDefaultNetviews(globalNetview string, localNetview string) (globalNetviewRef string, localNetviewRef string, err error)
CreateEADefinition(eadef EADefinition) (*EADefinition, error)
- CreateHostRecord(enabledns bool, recordName string, netview string, dnsview string, cidr string, ipAddr string, macAddress string, ea EA) (*HostRecord, error)
- CreateNetwork(netview string, cidr string, name string, comment string, ea EA) (*Network, error)
- CreateNetworkContainer(netview string, cidr string) (*NetworkContainer, error)
+ CreateHostRecord(enabledns bool, enabledhcp bool, recordName string, netview string, dnsview string, ipv4cidr string, ipv6cidr string, ipv4Addr string, ipv6Addr string, macAddr string, duid string, comment string, eas EA, aliases []string) (*HostRecord, error)
+ CreateNetwork(netview string, cidr string, isIPv6 bool, comment string, eas EA) (*Network, error)
+ CreateNetworkContainer(netview string, cidr string, isIPv6 bool, comment string, eas EA) (*NetworkContainer, error)
CreateNetworkView(name string) (*NetworkView, error)
CreatePTRRecord(netview string, dnsview string, recordname string, cidr string, ipAddr string, ea EA) (*RecordPTR, error)
+ CreateTXTRecord(recordname string, text string, ttl int, dnsview string) (*RecordTXT, error)
+ CreateZoneDelegated(fqdn string, delegate_to []NameServer) (*ZoneDelegated, error)
DeleteARecord(ref string) (string, error)
DeleteZoneAuth(ref string) (string, error)
DeleteCNAMERecord(ref string) (string, error)
DeleteFixedAddress(ref string) (string, error)
DeleteHostRecord(ref string) (string, error)
- DeleteNetwork(ref string, netview string) (string, error)
+ DeleteNetwork(ref string) (string, error)
+ DeleteNetworkContainer(ref string) (string, error)
DeleteNetworkView(ref string) (string, error)
DeletePTRRecord(ref string) (string, error)
+ DeleteTXTRecord(ref string) (string, error)
+ DeleteZoneDelegated(ref string) (string, error)
GetARecordByRef(ref string) (*RecordA, error)
- GetCNAMERecordByRef(ref string) (*RecordA, error)
+ GetCNAMERecordByRef(ref string) (*RecordCNAME, error)
GetEADefinition(name string) (*EADefinition, error)
- GetFixedAddress(netview string, cidr string, ipAddr string, macAddr string) (*FixedAddress, error)
+ GetFixedAddress(netview string, cidr string, ipAddr string, isIPv6 bool, macAddr string) (*FixedAddress, error)
GetFixedAddressByRef(ref string) (*FixedAddress, error)
- GetHostRecord(recordName string) (*HostRecord, error)
+ GetHostRecord(recordName string, ipv4addr string, ipv6addr string) (*HostRecord, error)
GetHostRecordByRef(ref string) (*HostRecord, error)
GetIpAddressFromHostRecord(host HostRecord) (string, error)
- GetNetwork(netview string, cidr string, ea EA) (*Network, error)
- GetNetworkContainer(netview string, cidr string) (*NetworkContainer, error)
+ GetNetwork(netview string, cidr string, isIPv6 bool, ea EA) (*Network, error)
+ GetNetworkByRef(ref string) (*Network, error)
+ GetNetworkContainer(netview string, cidr string, isIPv6 bool, eaSearch EA) (*NetworkContainer, error)
+ GetNetworkContainerByRef(ref string) (*NetworkContainer, error)
GetNetworkView(name string) (*NetworkView, error)
+ GetNetworkViewByRef(ref string) (*NetworkView, error)
GetPTRRecordByRef(ref string) (*RecordPTR, error)
GetZoneAuthByRef(ref string) (*ZoneAuth, error)
- ReleaseIP(netview string, cidr string, ipAddr string, macAddr string) (string, error)
- UpdateFixedAddress(fixedAddrRef string, matchclient string, macAddress string, vmID string, vmName string) (*FixedAddress, error)
- UpdateHostRecord(hostRref string, ipAddr string, macAddress string, vmID string, vmName string) (string, error)
- UpdateNetworkViewEA(ref string, addEA EA, removeEA EA) error
+ GetZoneDelegated(fqdn string) (*ZoneDelegated, error)
+ GetCapacityReport(name string) ([]CapacityReport, error)
+ GetUpgradeStatus(statusType string) ([]UpgradeStatus, error)
+ GetAllMembers() ([]Member, error)
+ GetGridInfo() ([]Grid, error)
+ GetGridLicense() ([]License, error)
+ ReleaseIP(netview string, cidr string, ipAddr string, isIPv6 bool, macAddr string) (string, error)
+ UpdateFixedAddress(fixedAddrRef string, name string, matchclient string, macAddress string, comment string, eas EA) (*FixedAddress, error)
+ UpdateHostRecord(hostRref string, enabledns bool, enabledhcp bool, name string, ipv4Addr string, ipv6Addr string, macAddress string, duid string, comment string, eas EA, aliases []string) (*HostRecord, error)
+ UpdateNetwork(ref string, setEas EA, comment string) (*Network, error)
+ UpdateNetworkContainer(ref string, setEas EA, comment string) (*NetworkContainer, error)
+ UpdateNetworkViewEA(ref string, setEas EA) error
+ UpdateZoneDelegated(ref string, delegate_to []NameServer) (*ZoneDelegated, error)
+}
+
+type NotFoundError struct {
+ msg string
+}
+
+func (e *NotFoundError) Error() string {
+ return "not found"
+}
+
+func NewNotFoundError(msg string) *NotFoundError {
+ return &NotFoundError{msg: msg}
}
type ObjectManager struct {
connector IBConnector
cmpType string
tenantID string
- // If OmitCloudAttrs is true no extra attributes for cloud are set
- OmitCloudAttrs bool
}
-func NewObjectManager(connector IBConnector, cmpType string, tenantID string) *ObjectManager {
- objMgr := new(ObjectManager)
+func NewObjectManager(connector IBConnector, cmpType string, tenantID string) IBObjectManager {
+ objMgr := &ObjectManager{}
objMgr.connector = connector
objMgr.cmpType = cmpType
@@ -65,28 +94,11 @@ func NewObjectManager(connector IBConnector, cmpType string, tenantID string) *O
return objMgr
}
-func (objMgr *ObjectManager) getBasicEA(cloudAPIOwned Bool) EA {
- ea := make(EA)
- if !objMgr.OmitCloudAttrs {
- ea["Cloud API Owned"] = cloudAPIOwned
- ea["CMP Type"] = objMgr.cmpType
- ea["Tenant ID"] = objMgr.tenantID
- }
- return ea
-}
-
-func (objMgr *ObjectManager) extendEA(ea EA) EA {
- eas := objMgr.getBasicEA(true)
- for k, v := range ea {
- eas[k] = v
- }
- return eas
-}
-
func (objMgr *ObjectManager) CreateNetworkView(name string) (*NetworkView, error) {
networkView := NewNetworkView(NetworkView{
Name: name,
- Ea: objMgr.getBasicEA(false)})
+ Ea: make(EA),
+ })
ref, err := objMgr.connector.CreateObject(networkView)
networkView.Ref = ref
@@ -122,14 +134,9 @@ func (objMgr *ObjectManager) CreateDefaultNetviews(globalNetview string, localNe
return
}
-func (objMgr *ObjectManager) CreateNetwork(netview string, cidr string, name string, comment string, ea EA) (*Network, error) {
+func (objMgr *ObjectManager) CreateNetwork(netview string, cidr string, isIPv6 bool, comment string, eas EA) (*Network, error) {
+ network := NewNetwork(netview, cidr, isIPv6, comment, eas)
- eas := objMgr.extendEA(ea)
- network := NewNetwork(netview, cidr, comment, eas)
-
- if name != "" {
- network.Ea["Network Name"] = name
- }
ref, err := objMgr.connector.CreateObject(network)
if err != nil {
return nil, err
@@ -139,53 +146,64 @@ func (objMgr *ObjectManager) CreateNetwork(netview string, cidr string, name str
return network, err
}
-func (objMgr *ObjectManager) CreateNetworkContainer(netview string, cidr string) (*NetworkContainer, error) {
- container := NewNetworkContainer(NetworkContainer{
- NetviewName: netview,
- Cidr: cidr,
- Ea: objMgr.getBasicEA(true)})
+func (objMgr *ObjectManager) CreateNetworkContainer(netview string, cidr string, isIPv6 bool, comment string, eas EA) (*NetworkContainer, error) {
+ container := NewNetworkContainer(netview, cidr, isIPv6, comment, eas)
ref, err := objMgr.connector.CreateObject(container)
- container.Ref = ref
+ if err != nil {
+ return nil, err
+ }
- return container, err
+ container.Ref = ref
+ return container, nil
}
func (objMgr *ObjectManager) GetNetworkView(name string) (*NetworkView, error) {
var res []NetworkView
- netview := NewNetworkView(NetworkView{Name: name})
-
- err := objMgr.connector.GetObject(netview, "", &res)
+ netview := NewNetworkView(NetworkView{})
+ sf := map[string]string{
+ "name": name,
+ }
+ queryParams := NewQueryParams(false, sf)
+ err := objMgr.connector.GetObject(netview, "", queryParams, &res)
- if err != nil || res == nil || len(res) == 0 {
+ if err != nil {
return nil, err
}
+ if res == nil || len(res) == 0 {
+ return nil, fmt.Errorf("network view '%s' not found", name)
+ }
return &res[0], nil
}
-func (objMgr *ObjectManager) UpdateNetworkViewEA(ref string, addEA EA, removeEA EA) error {
+func (objMgr *ObjectManager) GetNetworkViewByRef(ref string) (*NetworkView, error) {
+ res := NewNetworkView(NetworkView{})
+ queryParams := NewQueryParams(false, nil)
+ if err := objMgr.connector.GetObject(res, ref, queryParams, &res); err != nil {
+ return nil, err
+ }
+ if res == nil {
+ return nil, fmt.Errorf("network view not found")
+ }
+
+ return res, nil
+}
+
+func (objMgr *ObjectManager) UpdateNetworkViewEA(ref string, setEas EA) error {
var res NetworkView
nv := NetworkView{}
nv.returnFields = []string{"extattrs"}
- err := objMgr.connector.GetObject(&nv, ref, &res)
+ err := objMgr.connector.GetObject(
+ &nv, ref, NewQueryParams(false, nil), &res)
if err != nil {
return err
}
- for k, v := range addEA {
- res.Ea[k] = v
- }
-
- for k := range removeEA {
- _, ok := res.Ea[k]
- if ok {
- delete(res.Ea, k)
- }
- }
+ res.Ea = setEas
_, err = objMgr.connector.UpdateObject(&res, ref)
return err
@@ -212,65 +230,89 @@ func BuildNetworkFromRef(ref string) (*Network, error) {
m := r.FindStringSubmatch(ref)
if m == nil {
- return nil, fmt.Errorf("Format not matched")
+ return nil, fmt.Errorf("CIDR format not matched")
}
- return &Network{
- Ref: ref,
- NetviewName: m[2],
- Cidr: m[1],
- }, nil
+ newNet := NewNetwork(m[2], m[1], false, "", nil)
+ newNet.Ref = ref
+ return newNet, nil
}
-func (objMgr *ObjectManager) GetNetwork(netview string, cidr string, ea EA) (*Network, error) {
+func (objMgr *ObjectManager) GetNetwork(netview string, cidr string, isIPv6 bool, ea EA) (*Network, error) {
if netview != "" && cidr != "" {
var res []Network
- network := NewNetwork(netview, cidr, "", ea)
+ network := NewNetwork(netview, cidr, isIPv6, "", ea)
- if cidr != "" {
- network.Cidr = cidr
- }
+ network.Cidr = cidr
if ea != nil && len(ea) > 0 {
network.eaSearch = EASearch(ea)
}
- err := objMgr.connector.GetObject(network, "", &res)
+ sf := map[string]string{
+ "network_view": netview,
+ "network": cidr,
+ }
+ queryParams := NewQueryParams(false, sf)
+ err := objMgr.connector.GetObject(network, "", queryParams, &res)
if err != nil {
return nil, err
} else if res == nil || len(res) == 0 {
- return nil, fmt.Errorf("Network with cidr: %s in network view: %s is not found.", cidr, netview)
+ return nil, NewNotFoundError(
+ fmt.Sprintf(
+ "Network with cidr: %s in network view: %s is not found.",
+ cidr, netview))
}
return &res[0], nil
} else {
- err := fmt.Errorf("Both network view and cidr values are required")
+ err := fmt.Errorf("both network view and cidr values are required")
return nil, err
}
}
-func (objMgr *ObjectManager) GetNetworkWithRef(ref string) (*Network, error) {
- network := NewNetwork("", "", "", nil)
- err := objMgr.connector.GetObject(network, ref, &network)
+func (objMgr *ObjectManager) GetNetworkByRef(ref string) (*Network, error) {
+ r := regexp.MustCompile("^ipv6network\\/.+")
+ isIPv6 := r.MatchString(ref)
+
+ network := NewNetwork("", "", isIPv6, "", nil)
+ err := objMgr.connector.GetObject(network, ref, NewQueryParams(false, nil), network)
return network, err
}
-func (objMgr *ObjectManager) GetNetworkContainer(netview string, cidr string) (*NetworkContainer, error) {
+// TODO normalize IPv4 and IPv6 addresses
+func (objMgr *ObjectManager) GetNetworkContainer(netview string, cidr string, isIPv6 bool, eaSearch EA) (*NetworkContainer, error) {
var res []NetworkContainer
- nwcontainer := NewNetworkContainer(NetworkContainer{
- NetviewName: netview,
- Cidr: cidr})
+ nc := NewNetworkContainer(netview, cidr, isIPv6, "", nil)
+ nc.eaSearch = EASearch(eaSearch)
+ sf := map[string]string{
+ "network_view": netview,
+ "network": cidr,
+ }
+ queryParams := NewQueryParams(false, sf)
+ err := objMgr.connector.GetObject(nc, "", queryParams, &res)
+ if err != nil {
+ return nil, err
+ } else if res == nil || len(res) == 0 {
+ return nil, NewNotFoundError("network container not found")
+ }
+
+ return &res[0], nil
+}
- err := objMgr.connector.GetObject(nwcontainer, "", &res)
+func (objMgr *ObjectManager) GetNetworkContainerByRef(ref string) (*NetworkContainer, error) {
+ nc := NewNetworkContainer("", "", false, "", nil)
- if err != nil || res == nil || len(res) == 0 {
+ err := objMgr.connector.GetObject(
+ nc, ref, NewQueryParams(false, nil), nc)
+ if err != nil {
return nil, err
}
- return &res[0], nil
+ return nc, nil
}
func GetIPAddressFromRef(ref string) string {
@@ -284,64 +326,87 @@ func GetIPAddressFromRef(ref string) string {
return ""
}
-func (objMgr *ObjectManager) AllocateIP(netview string, cidr string, ipAddr string, macAddress string, name string, ea EA) (*FixedAddress, error) {
- if len(macAddress) == 0 {
- macAddress = MACADDR_ZERO
- }
-
- eas := objMgr.extendEA(ea)
+func (objMgr *ObjectManager) AllocateIP(
+ netview string,
+ cidr string,
+ ipAddr string,
+ isIPv6 bool,
+ macOrDuid string,
+ name string,
+ comment string,
+ eas EA) (*FixedAddress, error) {
- fixedAddr := NewFixedAddress(FixedAddress{
- NetviewName: netview,
- Cidr: cidr,
- Mac: macAddress,
- Name: name,
- Ea: eas})
-
- if ipAddr == "" {
- fixedAddr.IPAddress = fmt.Sprintf("func:nextavailableip:%s,%s", cidr, netview)
+ if isIPv6 {
+ if len(macOrDuid) == 0 {
+ return nil, fmt.Errorf("the DUID field cannot be left empty")
+ }
} else {
- fixedAddr.IPAddress = ipAddr
+ if len(macOrDuid) == 0 {
+ macOrDuid = MACADDR_ZERO
+ }
}
-
+ if ipAddr == "" {
+ ipAddr = fmt.Sprintf("func:nextavailableip:%s,%s", cidr, netview)
+ }
+ fixedAddr := NewFixedAddress(
+ netview, name, ipAddr, cidr, macOrDuid, "", eas, "", isIPv6, comment)
ref, err := objMgr.connector.CreateObject(fixedAddr)
+ if err != nil {
+ return nil, err
+ }
+
fixedAddr.Ref = ref
- fixedAddr.IPAddress = GetIPAddressFromRef(ref)
+ fixedAddr, err = objMgr.GetFixedAddressByRef(ref)
return fixedAddr, err
}
-func (objMgr *ObjectManager) AllocateNetwork(netview string, cidr string, prefixLen uint, name string, comment string, ea EA) (network *Network, err error) {
+func (objMgr *ObjectManager) AllocateNetwork(
+ netview string,
+ cidr string,
+ isIPv6 bool,
+ prefixLen uint,
+ comment string,
+ eas EA) (network *Network, err error) {
network = nil
cidr = fmt.Sprintf("func:nextavailablenetwork:%s,%s,%d", cidr, netview, prefixLen)
- eas := objMgr.extendEA(ea)
- networkReq := NewNetwork(netview, cidr, comment, eas)
- if name != "" {
- networkReq.Ea["Network Name"] = name
- }
+ networkReq := NewNetwork(netview, cidr, isIPv6, comment, eas)
ref, err := objMgr.connector.CreateObject(networkReq)
- if err == nil && len(ref) > 0 {
- network, err = BuildNetworkFromRef(ref)
+ if err == nil {
+ if isIPv6 {
+ network, err = BuildIPv6NetworkFromRef(ref)
+ } else {
+ network, err = BuildNetworkFromRef(ref)
+ }
}
return
}
-func (objMgr *ObjectManager) GetFixedAddress(netview string, cidr string, ipAddr string, macAddr string) (*FixedAddress, error) {
+func (objMgr *ObjectManager) GetFixedAddress(netview string, cidr string, ipAddr string, isIpv6 bool, macOrDuid string) (*FixedAddress, error) {
var res []FixedAddress
- fixedAddr := NewFixedAddress(FixedAddress{
- NetviewName: netview,
- Cidr: cidr,
- IPAddress: ipAddr})
-
- if macAddr != "" {
- fixedAddr.Mac = macAddr
+ fixedAddr := NewEmptyFixedAddress(isIpv6)
+ sf := map[string]string{
+ "network_view": netview,
+ "network": cidr,
+ }
+ if isIpv6 {
+ sf["ipv6addr"] = ipAddr
+ if macOrDuid != "" {
+ sf["duid"] = macOrDuid
+ }
+ } else {
+ sf["ipv4addr"] = ipAddr
+ if macOrDuid != "" {
+ sf["mac"] = macOrDuid
+ }
}
- err := objMgr.connector.GetObject(fixedAddr, "", &res)
+ queryParams := NewQueryParams(false, sf)
+ err := objMgr.connector.GetObject(fixedAddr, "", queryParams, &res)
if err != nil || res == nil || len(res) == 0 {
return nil, err
@@ -351,8 +416,12 @@ func (objMgr *ObjectManager) GetFixedAddress(netview string, cidr string, ipAddr
}
func (objMgr *ObjectManager) GetFixedAddressByRef(ref string) (*FixedAddress, error) {
- fixedAddr := NewFixedAddress(FixedAddress{})
- err := objMgr.connector.GetObject(fixedAddr, ref, &fixedAddr)
+ r := regexp.MustCompile("^ipv6fixedaddress/.+")
+ isIPv6 := r.MatchString(ref)
+
+ fixedAddr := NewEmptyFixedAddress(isIPv6)
+ err := objMgr.connector.GetObject(
+ fixedAddr, ref, NewQueryParams(false, nil), &fixedAddr)
return fixedAddr, err
}
@@ -362,9 +431,14 @@ func (objMgr *ObjectManager) DeleteFixedAddress(ref string) (string, error) {
// validation for match_client
func validateMatchClient(value string) bool {
- match_client := [5]string{"MAC_ADDRESS", "CLIENT_ID", "RESERVED", "CIRCUIT_ID", "REMOTE_ID"}
-
- for _, val := range match_client {
+ matchClientList := [5]string{
+ "MAC_ADDRESS",
+ "CLIENT_ID",
+ "RESERVED",
+ "CIRCUIT_ID",
+ "REMOTE_ID"}
+
+ for _, val := range matchClientList {
if val == value {
return true
}
@@ -372,43 +446,47 @@ func validateMatchClient(value string) bool {
return false
}
-func (objMgr *ObjectManager) UpdateFixedAddress(fixedAddrRef string, matchClient string, macAddress string, vmID string, vmName string) (*FixedAddress, error) {
- updateFixedAddr := NewFixedAddress(FixedAddress{Ref: fixedAddrRef})
-
- if len(macAddress) != 0 {
- updateFixedAddr.Mac = macAddress
- }
-
- ea := objMgr.getBasicEA(true)
- if vmID != "" {
- ea["VM ID"] = vmID
- updateFixedAddr.Ea = ea
- }
- if vmName != "" {
- ea["VM Name"] = vmName
- updateFixedAddr.Ea = ea
- }
- if matchClient != "" {
- if validateMatchClient(matchClient) {
- updateFixedAddr.MatchClient = matchClient
- } else {
+func (objMgr *ObjectManager) UpdateFixedAddress(
+ fixedAddrRef string,
+ name string,
+ matchClient string,
+ macOrDuid string,
+ comment string,
+ eas EA) (*FixedAddress, error) {
+ r := regexp.MustCompile("^ipv6fixedaddress\\/.+")
+ isIPv6 := r.MatchString(fixedAddrRef)
+ if !isIPv6 {
+ if !validateMatchClient(matchClient) {
return nil, fmt.Errorf("wrong value for match_client passed %s \n ", matchClient)
}
}
+ updateFixedAddr := NewFixedAddress(
+ "", name, "", "",
+ macOrDuid, matchClient, eas, fixedAddrRef, isIPv6, comment)
refResp, err := objMgr.connector.UpdateObject(updateFixedAddr, fixedAddrRef)
updateFixedAddr.Ref = refResp
+
return updateFixedAddr, err
}
-func (objMgr *ObjectManager) ReleaseIP(netview string, cidr string, ipAddr string, macAddr string) (string, error) {
- fixAddress, _ := objMgr.GetFixedAddress(netview, cidr, ipAddr, macAddr)
+func (objMgr *ObjectManager) ReleaseIP(netview string, cidr string, ipAddr string, isIpv6 bool, macOrDuid string) (string, error) {
+ fixAddress, _ := objMgr.GetFixedAddress(netview, cidr, ipAddr, isIpv6, macOrDuid)
if fixAddress == nil {
return "", nil
}
return objMgr.connector.DeleteObject(fixAddress.Ref)
}
+func (objMgr *ObjectManager) DeleteNetworkContainer(ref string) (string, error) {
+ ncRegExp := regexp.MustCompile("^(ipv6)?networkcontainer\\/.+")
+ if !ncRegExp.MatchString(ref) {
+ return "", fmt.Errorf("'ref' does not reference a network container")
+ }
+
+ return objMgr.connector.DeleteObject(ref)
+}
+
func (objMgr *ObjectManager) DeleteNetwork(ref string) (string, error) {
return objMgr.connector.DeleteObject(ref)
}
@@ -422,7 +500,11 @@ func (objMgr *ObjectManager) GetEADefinition(name string) (*EADefinition, error)
eadef := NewEADefinition(EADefinition{Name: name})
- err := objMgr.connector.GetObject(eadef, "", &res)
+ sf := map[string]string{
+ "name": name,
+ }
+ queryParams := NewQueryParams(false, sf)
+ err := objMgr.connector.GetObject(eadef, "", queryParams, &res)
if err != nil || res == nil || len(res) == 0 {
return nil, err
@@ -440,52 +522,102 @@ func (objMgr *ObjectManager) CreateEADefinition(eadef EADefinition) (*EADefiniti
return newEadef, err
}
-func (objMgr *ObjectManager) CreateHostRecord(enabledns bool, recordName string, netview string, dnsview string, cidr string, ipAddr string, macAddress string, ea EA) (*HostRecord, error) {
+func BuildIPv6NetworkFromRef(ref string) (*Network, error) {
+ // ipv6network/ZG5zLm5ldHdvcmskODkuMC4wLjAvMjQvMjU:2001%3Adb8%3Aabcd%3A0012%3A%3A0/64/global_view
+ r := regexp.MustCompile(`ipv6network/[^:]+:(([^\/]+)\/\d+)\/(.+)`)
+ m := r.FindStringSubmatch(ref)
- eas := objMgr.extendEA(ea)
+ if m == nil {
+ return nil, fmt.Errorf("CIDR format not matched")
+ }
- recordHostIpAddr := NewHostRecordIpv4Addr(HostRecordIpv4Addr{Mac: macAddress})
+ cidr, err := url.QueryUnescape(m[1])
+ if err != nil {
+ return nil, fmt.Errorf(
+ "cannot extract network CIDR information from the reference '%s': %s",
+ ref, err.Error())
+ }
- if ipAddr == "" {
- recordHostIpAddr.Ipv4Addr = fmt.Sprintf("func:nextavailableip:%s,%s", cidr, netview)
- } else {
- recordHostIpAddr.Ipv4Addr = ipAddr
+ if _, _, err = net.ParseCIDR(cidr); err != nil {
+ return nil, fmt.Errorf("CIDR format not matched")
}
- enableDNS := new(bool)
- *enableDNS = enabledns
- recordHostIpAddrSlice := []HostRecordIpv4Addr{*recordHostIpAddr}
- recordHost := NewHostRecord(HostRecord{
- Name: recordName,
- EnableDns: enableDNS,
- NetworkView: netview,
- View: dnsview,
- Ipv4Addrs: recordHostIpAddrSlice,
- Ea: eas})
+ newNet := NewNetwork(m[3], cidr, true, "", nil)
+ newNet.Ref = ref
+
+ return newNet, nil
+}
+
+func (objMgr *ObjectManager) CreateHostRecord(
+ enabledns bool,
+ enabledhcp bool,
+ recordName string,
+ netview string,
+ dnsview string,
+ ipv4cidr string,
+ ipv6cidr string,
+ ipv4Addr string,
+ ipv6Addr string,
+ macAddr string,
+ duid string,
+ comment string,
+ eas EA,
+ aliases []string) (*HostRecord, error) {
+
+ if ipv4Addr == "" && ipv4cidr != "" {
+ ipv4Addr = fmt.Sprintf("func:nextavailableip:%s,%s", ipv4cidr, netview)
+ }
+ if ipv6Addr == "" && ipv6cidr != "" {
+ ipv6Addr = fmt.Sprintf("func:nextavailableip:%s,%s", ipv6cidr, netview)
+ }
+ recordHost := NewEmptyHostRecord()
+ recordHostIpv6AddrSlice := []HostRecordIpv6Addr{}
+ recordHostIpv4AddrSlice := []HostRecordIpv4Addr{}
+ if ipv6Addr != "" {
+ recordHostIpv6Addr := NewHostRecordIpv6Addr(ipv6Addr, duid, &enabledhcp, "")
+ recordHostIpv6AddrSlice = []HostRecordIpv6Addr{*recordHostIpv6Addr}
+ }
+ if ipv4Addr != "" {
+ recordHostIpAddr := NewHostRecordIpv4Addr(ipv4Addr, macAddr, &enabledhcp, "")
+
+ recordHostIpv4AddrSlice = []HostRecordIpv4Addr{*recordHostIpAddr}
+ }
+ recordHost = NewHostRecord(
+ netview, recordName, "", "", recordHostIpv4AddrSlice, recordHostIpv6AddrSlice,
+ eas, &enabledns, dnsview, "", "", comment, aliases)
ref, err := objMgr.connector.CreateObject(recordHost)
if err != nil {
return nil, err
}
recordHost.Ref = ref
- err = objMgr.connector.GetObject(recordHost, ref, &recordHost)
+ err = objMgr.connector.GetObject(
+ recordHost, ref, NewQueryParams(false, nil), &recordHost)
return recordHost, err
}
func (objMgr *ObjectManager) GetHostRecordByRef(ref string) (*HostRecord, error) {
- recordHost := NewHostRecord(HostRecord{})
- err := objMgr.connector.GetObject(recordHost, ref, &recordHost)
+ recordHost := NewEmptyHostRecord()
+ err := objMgr.connector.GetObject(
+ recordHost, ref, NewQueryParams(false, nil), &recordHost)
return recordHost, err
}
-func (objMgr *ObjectManager) GetHostRecord(recordName string) (*HostRecord, error) {
+func (objMgr *ObjectManager) GetHostRecord(recordName string, ipv4addr string, ipv6addr string) (*HostRecord, error) {
var res []HostRecord
- recordHost := NewHostRecord(HostRecord{})
- if recordName != "" {
- recordHost.Name = recordName
- }
+ recordHost := NewEmptyHostRecord()
- err := objMgr.connector.GetObject(recordHost, "", &res)
+ sf := map[string]string{
+ "name": recordName,
+ }
+ if ipv4addr != "" {
+ sf["ipv4addr"] = ipv4addr
+ }
+ if ipv6addr != "" {
+ sf["ipv6addr"] = ipv6addr
+ }
+ queryParams := NewQueryParams(false, sf)
+ err := objMgr.connector.GetObject(recordHost, "", queryParams, &res)
if err != nil || res == nil || len(res) == 0 {
return nil, err
@@ -495,42 +627,117 @@ func (objMgr *ObjectManager) GetHostRecord(recordName string) (*HostRecord, erro
}
func (objMgr *ObjectManager) GetIpAddressFromHostRecord(host HostRecord) (string, error) {
- err := objMgr.connector.GetObject(&host, host.Ref, &host)
+ err := objMgr.connector.GetObject(
+ &host, host.Ref, NewQueryParams(false, nil), &host)
return host.Ipv4Addrs[0].Ipv4Addr, err
}
-func (objMgr *ObjectManager) UpdateHostRecord(hostRref string, ipAddr string, macAddress string, vmID string, vmName string) (string, error) {
+func (objMgr *ObjectManager) UpdateHostRecord(
+ hostRref string,
+ enabledns bool,
+ enabledhcp bool,
+ name string,
+ ipv4Addr string,
+ ipv6Addr string,
+ macAddress string,
+ duid string,
+ comment string,
+ eas EA,
+ aliases []string) (*HostRecord, error) {
- recordHostIpAddr := NewHostRecordIpv4Addr(HostRecordIpv4Addr{Mac: macAddress, Ipv4Addr: ipAddr})
- recordHostIpAddrSlice := []HostRecordIpv4Addr{*recordHostIpAddr}
- updateHostRecord := NewHostRecord(HostRecord{Ipv4Addrs: recordHostIpAddrSlice})
-
- ea := objMgr.getBasicEA(true)
- if vmID != "" {
- ea["VM ID"] = vmID
- updateHostRecord.Ea = ea
+ enableDNS := new(bool)
+ *enableDNS = enabledns
+ enableDHCP := new(bool)
+ *enableDHCP = enabledhcp
+ recordHostIpv4AddrSlice := []HostRecordIpv4Addr{}
+ recordHostIpv6AddrSlice := []HostRecordIpv6Addr{}
+ if ipv4Addr != "" {
+ recordHostIpAddr := NewHostRecordIpv4Addr(ipv4Addr, macAddress, enableDHCP, "")
+ recordHostIpv4AddrSlice = []HostRecordIpv4Addr{*recordHostIpAddr}
}
-
- if vmName != "" {
- ea["VM Name"] = vmName
- updateHostRecord.Ea = ea
+ if ipv6Addr != "" {
+ recordHostIpAddr := NewHostRecordIpv6Addr(ipv6Addr, duid, enableDHCP, "")
+ recordHostIpv6AddrSlice = []HostRecordIpv6Addr{*recordHostIpAddr}
}
+ updateHostRecord := NewHostRecord(
+ "", name, "", "", recordHostIpv4AddrSlice, recordHostIpv6AddrSlice,
+ eas, enableDNS, "", "", hostRref, comment, aliases)
ref, err := objMgr.connector.UpdateObject(updateHostRecord, hostRref)
- return ref, err
+ updateHostRecord.Ref = ref
+ return updateHostRecord, err
}
func (objMgr *ObjectManager) DeleteHostRecord(ref string) (string, error) {
return objMgr.connector.DeleteObject(ref)
}
-func (objMgr *ObjectManager) CreateARecord(netview string, dnsview string, recordname string, cidr string, ipAddr string, ea EA) (*RecordA, error) {
+// UpdateNetwork updates comment and EA parameters.
+// EAs which exist will be updated,
+// those which do exist but not in setEas map, will be deleted,
+// EAs which do not exist will be created as new.
+func (objMgr *ObjectManager) UpdateNetwork(
+ ref string,
+ setEas EA,
+ comment string) (*Network, error) {
- eas := objMgr.extendEA(ea)
+ r := regexp.MustCompile("^ipv6network\\/.+")
+ isIPv6 := r.MatchString(ref)
- recordA := NewRecordA(RecordA{
- View: dnsview,
- Name: recordname,
- Ea: eas})
+ nw := NewNetwork("", "", isIPv6, "", nil)
+ err := objMgr.connector.GetObject(
+ nw, ref, NewQueryParams(false, nil), nw)
+
+ if err != nil {
+ return nil, err
+ }
+
+ nw.Ea = setEas
+ nw.Comment = comment
+
+ newRef, err := objMgr.connector.UpdateObject(nw, ref)
+ if err != nil {
+ return nil, err
+ }
+
+ nw.Ref = newRef
+ return nw, nil
+}
+
+func (objMgr *ObjectManager) UpdateNetworkContainer(
+ ref string,
+ setEas EA,
+ comment string) (*NetworkContainer, error) {
+
+ nc := &NetworkContainer{}
+ nc.returnFields = []string{"extattrs", "comment"}
+
+ err := objMgr.connector.GetObject(
+ nc, ref, NewQueryParams(false, nil), nc)
+ if err != nil {
+ return nil, err
+ }
+
+ nc.Ea = setEas
+ nc.Comment = comment
+
+ reference, err := objMgr.connector.UpdateObject(nc, ref)
+ if err != nil {
+ return nil, err
+ }
+
+ nc.Ref = reference
+ return nc, nil
+}
+
+func (objMgr *ObjectManager) CreateARecord(
+ netview string,
+ dnsview string,
+ recordname string,
+ cidr string,
+ ipAddr string,
+ eas EA) (*RecordA, error) {
+
+ recordA := NewRecordA(dnsview, "", recordname, "", eas, "")
if ipAddr == "" {
recordA.Ipv4Addr = fmt.Sprintf("func:nextavailableip:%s,%s", cidr, netview)
@@ -543,17 +750,20 @@ func (objMgr *ObjectManager) CreateARecord(netview string, dnsview string, recor
}
func (objMgr *ObjectManager) GetARecordByRef(ref string) (*RecordA, error) {
- recordA := NewRecordA(RecordA{})
- err := objMgr.connector.GetObject(recordA, ref, &recordA)
+ recordA := NewEmptyRecordA()
+ err := objMgr.connector.GetObject(
+ recordA, ref, NewQueryParams(false, nil), &recordA)
return recordA, err
}
func (objMgr *ObjectManager) DeleteARecord(ref string) (string, error) {
return objMgr.connector.DeleteObject(ref)
}
-func (objMgr *ObjectManager) CreateCNAMERecord(canonical string, recordname string, dnsview string, ea EA) (*RecordCNAME, error) {
-
- eas := objMgr.extendEA(ea)
+func (objMgr *ObjectManager) CreateCNAMERecord(
+ canonical string,
+ recordname string,
+ dnsview string,
+ eas EA) (*RecordCNAME, error) {
recordCNAME := NewRecordCNAME(RecordCNAME{
View: dnsview,
@@ -568,7 +778,8 @@ func (objMgr *ObjectManager) CreateCNAMERecord(canonical string, recordname stri
func (objMgr *ObjectManager) GetCNAMERecordByRef(ref string) (*RecordCNAME, error) {
recordCNAME := NewRecordCNAME(RecordCNAME{})
- err := objMgr.connector.GetObject(recordCNAME, ref, &recordCNAME)
+ err := objMgr.connector.GetObject(
+ recordCNAME, ref, NewQueryParams(false, nil), &recordCNAME)
return recordCNAME, err
}
@@ -593,7 +804,8 @@ func (objMgr *ObjectManager) CreateTXTRecord(recordname string, text string, ttl
func (objMgr *ObjectManager) GetTXTRecordByRef(ref string) (*RecordTXT, error) {
recordTXT := NewRecordTXT(RecordTXT{})
- err := objMgr.connector.GetObject(recordTXT, ref, &recordTXT)
+ err := objMgr.connector.GetObject(
+ recordTXT, ref, NewQueryParams(false, nil), &recordTXT)
return recordTXT, err
}
@@ -603,9 +815,13 @@ func (objMgr *ObjectManager) GetTXTRecord(name string) (*RecordTXT, error) {
}
var res []RecordTXT
- recordTXT := NewRecordTXT(RecordTXT{Name: name})
+ recordTXT := NewRecordTXT(RecordTXT{})
- err := objMgr.connector.GetObject(recordTXT, "", &res)
+ sf := map[string]string{
+ "name": name,
+ }
+ queryParams := NewQueryParams(false, sf)
+ err := objMgr.connector.GetObject(recordTXT, "", queryParams, &res)
if err != nil || res == nil || len(res) == 0 {
return nil, err
@@ -619,7 +835,11 @@ func (objMgr *ObjectManager) UpdateTXTRecord(recordname string, text string) (*R
recordTXT := NewRecordTXT(RecordTXT{Name: recordname})
- err := objMgr.connector.GetObject(recordTXT, "", &res)
+ sf := map[string]string{
+ "name": recordname,
+ }
+ queryParams := NewQueryParams(false, sf)
+ err := objMgr.connector.GetObject(recordTXT, "", queryParams, &res)
if len(res) == 0 {
return nil, nil
@@ -642,9 +862,13 @@ func (objMgr *ObjectManager) DeleteTXTRecord(ref string) (string, error) {
return objMgr.connector.DeleteObject(ref)
}
-func (objMgr *ObjectManager) CreatePTRRecord(netview string, dnsview string, recordname string, cidr string, ipAddr string, ea EA) (*RecordPTR, error) {
-
- eas := objMgr.extendEA(ea)
+func (objMgr *ObjectManager) CreatePTRRecord(
+ netview string,
+ dnsview string,
+ recordname string,
+ cidr string,
+ ipAddr string,
+ eas EA) (*RecordPTR, error) {
recordPTR := NewRecordPTR(RecordPTR{
View: dnsview,
@@ -663,7 +887,8 @@ func (objMgr *ObjectManager) CreatePTRRecord(netview string, dnsview string, rec
func (objMgr *ObjectManager) GetPTRRecordByRef(ref string) (*RecordPTR, error) {
recordPTR := NewRecordPTR(RecordPTR{})
- err := objMgr.connector.GetObject(recordPTR, ref, &recordPTR)
+ err := objMgr.connector.GetObject(
+ recordPTR, ref, NewQueryParams(false, nil), &recordPTR)
return recordPTR, err
}
@@ -675,7 +900,7 @@ func (objMgr *ObjectManager) DeletePTRRecord(ref string) (string, error) {
func (objMgr *ObjectManager) CreateMultiObject(req *MultiRequest) ([]map[string]interface{}, error) {
conn := objMgr.connector.(*Connector)
- queryParams := QueryParams{forceProxy: false}
+ queryParams := NewQueryParams(false, nil)
res, err := conn.makeRequest(CREATE, req, "", queryParams)
if err != nil {
@@ -702,8 +927,13 @@ func (objMgr *ObjectManager) GetUpgradeStatus(statusType string) ([]UpgradeStatu
msg := fmt.Sprintf("Status type can not be nil")
return res, errors.New(msg)
}
- upgradestatus := NewUpgradeStatus(UpgradeStatus{Type: statusType})
- err := objMgr.connector.GetObject(upgradestatus, "", &res)
+ upgradestatus := NewUpgradeStatus(UpgradeStatus{})
+
+ sf := map[string]string{
+ "type": statusType,
+ }
+ queryParams := NewQueryParams(false, sf)
+ err := objMgr.connector.GetObject(upgradestatus, "", queryParams, &res)
return res, err
}
@@ -713,7 +943,8 @@ func (objMgr *ObjectManager) GetAllMembers() ([]Member, error) {
var res []Member
memberObj := NewMember(Member{})
- err := objMgr.connector.GetObject(memberObj, "", &res)
+ err := objMgr.connector.GetObject(
+ memberObj, "", NewQueryParams(false, nil), &res)
return res, err
}
@@ -721,9 +952,13 @@ func (objMgr *ObjectManager) GetAllMembers() ([]Member, error) {
func (objMgr *ObjectManager) GetCapacityReport(name string) ([]CapacityReport, error) {
var res []CapacityReport
- capacityObj := CapacityReport{Name: name}
- capacityReport := NewCapcityReport(capacityObj)
- err := objMgr.connector.GetObject(capacityReport, "", &res)
+ capacityReport := NewCapcityReport(CapacityReport{})
+
+ sf := map[string]string{
+ "name": name,
+ }
+ queryParams := NewQueryParams(false, sf)
+ err := objMgr.connector.GetObject(capacityReport, "", queryParams, &res)
return res, err
}
@@ -732,7 +967,8 @@ func (objMgr *ObjectManager) GetLicense() ([]License, error) {
var res []License
licenseObj := NewLicense(License{})
- err := objMgr.connector.GetObject(licenseObj, "", &res)
+ err := objMgr.connector.GetObject(
+ licenseObj, "", NewQueryParams(false, nil), &res)
return res, err
}
@@ -741,7 +977,8 @@ func (objMgr *ObjectManager) GetGridLicense() ([]License, error) {
var res []License
licenseObj := NewGridLicense(License{})
- err := objMgr.connector.GetObject(licenseObj, "", &res)
+ err := objMgr.connector.GetObject(
+ licenseObj, "", NewQueryParams(false, nil), &res)
return res, err
}
@@ -750,14 +987,15 @@ func (objMgr *ObjectManager) GetGridInfo() ([]Grid, error) {
var res []Grid
gridObj := NewGrid(Grid{})
- err := objMgr.connector.GetObject(gridObj, "", &res)
+ err := objMgr.connector.GetObject(
+ gridObj, "", NewQueryParams(false, nil), &res)
return res, err
}
// CreateZoneAuth creates zones and subs by passing fqdn
-func (objMgr *ObjectManager) CreateZoneAuth(fqdn string, ea EA) (*ZoneAuth, error) {
-
- eas := objMgr.extendEA(ea)
+func (objMgr *ObjectManager) CreateZoneAuth(
+ fqdn string,
+ eas EA) (*ZoneAuth, error) {
zoneAuth := NewZoneAuth(ZoneAuth{
Fqdn: fqdn,
@@ -769,15 +1007,15 @@ func (objMgr *ObjectManager) CreateZoneAuth(fqdn string, ea EA) (*ZoneAuth, erro
}
// Retreive a authortative zone by ref
-func (objMgr *ObjectManager) GetZoneAuthByRef(ref string) (ZoneAuth, error) {
- var res ZoneAuth
+func (objMgr *ObjectManager) GetZoneAuthByRef(ref string) (*ZoneAuth, error) {
+ res := NewZoneAuth(ZoneAuth{})
if ref == "" {
- return res, nil
+ return nil, fmt.Errorf("empty reference to an object is not allowed")
}
- zoneAuth := NewZoneAuth(ZoneAuth{})
- err := objMgr.connector.GetObject(zoneAuth, ref, &res)
+ err := objMgr.connector.GetObject(
+ res, ref, NewQueryParams(false, nil), res)
return res, err
}
@@ -791,7 +1029,8 @@ func (objMgr *ObjectManager) GetZoneAuth() ([]ZoneAuth, error) {
var res []ZoneAuth
zoneAuth := NewZoneAuth(ZoneAuth{})
- err := objMgr.connector.GetObject(zoneAuth, "", &res)
+ err := objMgr.connector.GetObject(
+ zoneAuth, "", NewQueryParams(false, nil), &res)
return res, err
}
@@ -803,9 +1042,13 @@ func (objMgr *ObjectManager) GetZoneDelegated(fqdn string) (*ZoneDelegated, erro
}
var res []ZoneDelegated
- zoneDelegated := NewZoneDelegated(ZoneDelegated{Fqdn: fqdn})
+ zoneDelegated := NewZoneDelegated(ZoneDelegated{})
- err := objMgr.connector.GetObject(zoneDelegated, "", &res)
+ sf := map[string]string{
+ "fqdn": fqdn,
+ }
+ queryParams := NewQueryParams(false, sf)
+ err := objMgr.connector.GetObject(zoneDelegated, "", queryParams, &res)
if err != nil || res == nil || len(res) == 0 {
return nil, err
diff --git a/vendor/github.com/infobloxopen/infoblox-go-client/objects.go b/vendor/github.com/infobloxopen/infoblox-go-client/objects.go
index afd5b91f8..9e343b8d7 100644
--- a/vendor/github.com/infobloxopen/infoblox-go-client/objects.go
+++ b/vendor/github.com/infobloxopen/infoblox-go-client/objects.go
@@ -46,7 +46,7 @@ type NetworkView struct {
IBBase `json:"-"`
Ref string `json:"_ref,omitempty"`
Name string `json:"name,omitempty"`
- Ea EA `json:"extattrs,omitempty"`
+ Ea EA `json:"extattrs"`
}
func NewNetworkView(nv NetworkView) *NetworkView {
@@ -93,18 +93,22 @@ type Network struct {
Ref string `json:"_ref,omitempty"`
NetviewName string `json:"network_view,omitempty"`
Cidr string `json:"network,omitempty"`
- Ea EA `json:"extattrs,omitempty"`
- Comment string `json:"comment,omitempty"`
+ Ea EA `json:"extattrs"`
+ Comment string `json:"comment"`
}
-func NewNetwork(netview string, cidr string, comment string, ea EA) *Network {
+func NewNetwork(netview string, cidr string, isIPv6 bool, comment string, ea EA) *Network {
var res Network
res.NetviewName = netview
res.Cidr = cidr
res.Ea = ea
res.Comment = comment
- res.objectType = "network"
- res.returnFields = []string{"extattrs", "network", "network_view", "comment"}
+ if isIPv6 {
+ res.objectType = "ipv6network"
+ } else {
+ res.objectType = "network"
+ }
+ res.returnFields = []string{"extattrs", "network", "comment"}
return &res
}
@@ -287,15 +291,26 @@ type NetworkContainer struct {
Ref string `json:"_ref,omitempty"`
NetviewName string `json:"network_view,omitempty"`
Cidr string `json:"network,omitempty"`
- Ea EA `json:"extattrs,omitempty"`
+ Comment string `json:"comment"`
+ Ea EA `json:"extattrs"`
}
-func NewNetworkContainer(nc NetworkContainer) *NetworkContainer {
- res := nc
- res.objectType = "networkcontainer"
- res.returnFields = []string{"extattrs", "network", "network_view"}
+func NewNetworkContainer(netview, cidr string, isIPv6 bool, comment string, ea EA) *NetworkContainer {
+ nc := NetworkContainer{
+ NetviewName: netview,
+ Cidr: cidr,
+ Ea: ea,
+ Comment: comment,
+ }
- return &res
+ if isIPv6 {
+ nc.objectType = "ipv6networkcontainer"
+ } else {
+ nc.objectType = "networkcontainer"
+ }
+ nc.returnFields = []string{"extattrs", "network", "network_view", "comment"}
+
+ return &nc
}
type FixedAddress struct {
@@ -303,30 +318,81 @@ type FixedAddress struct {
Ref string `json:"_ref,omitempty"`
NetviewName string `json:"network_view,omitempty"`
Cidr string `json:"network,omitempty"`
- IPAddress string `json:"ipv4addr,omitempty"`
+ Comment string `json:"comment"`
+ IPv4Address string `json:"ipv4addr,omitempty"`
+ IPv6Address string `json:"ipv6addr,omitempty"`
+ Duid string `json:"duid,omitempty"`
Mac string `json:"mac,omitempty"`
Name string `json:"name,omitempty"`
MatchClient string `json:"match_client,omitempty"`
- Ea EA `json:"extattrs,omitempty"`
+ Ea EA `json:"extattrs"`
}
/*This is a general struct to add query params used in makeRequest*/
type QueryParams struct {
forceProxy bool
+
+ searchFields map[string]string
}
-func NewFixedAddress(fixedAddr FixedAddress) *FixedAddress {
- res := fixedAddr
- res.objectType = "fixedaddress"
- res.returnFields = []string{"extattrs", "ipv4addr", "mac", "name", "network", "network_view"}
+func NewQueryParams(forceProxy bool, searchFields map[string]string) *QueryParams {
+ qp := QueryParams{forceProxy: forceProxy}
+ if searchFields != nil {
+ qp.searchFields = searchFields
+ } else {
+ qp.searchFields = make(map[string]string)
+ }
- return &res
+ return &qp
+}
+
+func NewEmptyFixedAddress(isIPv6 bool) *FixedAddress {
+ res := &FixedAddress{}
+ res.Ea = make(EA)
+ if isIPv6 {
+ res.objectType = "ipv6fixedaddress"
+ res.returnFields = []string{"extattrs", "ipv6addr", "duid", "name", "network", "network_view", "comment"}
+ } else {
+ res.objectType = "fixedaddress"
+ res.returnFields = []string{"extattrs", "ipv4addr", "mac", "name", "network", "network_view", "comment"}
+ }
+ return res
+}
+
+func NewFixedAddress(
+ netView string,
+ name string,
+ ipAddr string,
+ cidr string,
+ macOrDuid string,
+ clients string,
+ eas EA,
+ ref string,
+ isIPv6 bool,
+ comment string) *FixedAddress {
+
+ res := NewEmptyFixedAddress(isIPv6)
+ res.NetviewName = netView
+ res.Name = name
+ res.Cidr = cidr
+ res.MatchClient = clients
+ res.Ea = eas
+ res.Ref = ref
+ res.Comment = comment
+ if isIPv6 {
+ res.IPv6Address = ipAddr
+ res.Duid = macOrDuid
+ } else {
+ res.IPv4Address = ipAddr
+ res.Mac = macOrDuid
+ }
+ return res
}
type EADefinition struct {
IBBase `json:"-"`
Ref string `json:"_ref,omitempty"`
- Comment string `json:"comment,omitempty"`
+ Comment string `json:"comment"`
Flags string `json:"flags,omitempty"`
ListValues []EADefListValue `json:"list_values,omitempty"`
Name string `json:"name,omitempty"`
@@ -363,15 +429,34 @@ type RecordA struct {
Name string `json:"name,omitempty"`
View string `json:"view,omitempty"`
Zone string `json:"zone,omitempty"`
- Ea EA `json:"extattrs,omitempty"`
+ Ea EA `json:"extattrs"`
}
-func NewRecordA(ra RecordA) *RecordA {
- res := ra
+func NewEmptyRecordA() *RecordA {
+ res := &RecordA{}
res.objectType = "record:a"
res.returnFields = []string{"extattrs", "ipv4addr", "name", "view", "zone"}
- return &res
+ return res
+}
+
+func NewRecordA(
+ view string,
+ zone string,
+ name string,
+ ipAddr string,
+ eas EA,
+ ref string) *RecordA {
+
+ res := NewEmptyRecordA()
+ res.View = view
+ res.Zone = zone
+ res.Name = name
+ res.Ipv4Addr = ipAddr
+ res.Ea = eas
+ res.Ref = ref
+
+ return res
}
type RecordPTR struct {
@@ -382,7 +467,7 @@ type RecordPTR struct {
PtrdName string `json:"ptrdname,omitempty"`
View string `json:"view,omitempty"`
Zone string `json:"zone,omitempty"`
- Ea EA `json:"extattrs,omitempty"`
+ Ea EA `json:"extattrs"`
}
func NewRecordPTR(rptr RecordPTR) *RecordPTR {
@@ -400,7 +485,7 @@ type RecordCNAME struct {
Name string `json:"name,omitempty"`
View string `json:"view,omitempty"`
Zone string `json:"zone,omitempty"`
- Ea EA `json:"extattrs,omitempty"`
+ Ea EA `json:"extattrs"`
}
func NewRecordCNAME(rc RecordCNAME) *RecordCNAME {
@@ -412,18 +497,67 @@ func NewRecordCNAME(rc RecordCNAME) *RecordCNAME {
}
type HostRecordIpv4Addr struct {
- IBBase `json:"-"`
- Ipv4Addr string `json:"ipv4addr,omitempty"`
- Ref string `json:"_ref,omitempty"`
- Mac string `json:"mac,omitempty"`
- View string `json:"view,omitempty"`
- Cidr string `json:"network,omitempty"`
+ IBBase `json:"-"`
+ Ipv4Addr string `json:"ipv4addr,omitempty"`
+ Ref string `json:"_ref,omitempty"`
+ Mac string `json:"mac,omitempty"`
+ View string `json:"view,omitempty"`
+ Cidr string `json:"network,omitempty"`
+ EnableDHCP *bool `json:"configure_for_dhcp,omitempty"`
}
-func NewHostRecordIpv4Addr(hostAddr HostRecordIpv4Addr) *HostRecordIpv4Addr {
- res := hostAddr
+func NewEmptyHostRecordIpv4Addr() *HostRecordIpv4Addr {
+ res := &HostRecordIpv4Addr{}
res.objectType = "record:host_ipv4addr"
- return &res
+
+ return res
+}
+
+func NewHostRecordIpv4Addr(
+ ipAddr string,
+ macAddr string,
+ enableDHCP *bool,
+ ref string) *HostRecordIpv4Addr {
+
+ res := NewEmptyHostRecordIpv4Addr()
+ res.Ipv4Addr = ipAddr
+ res.Mac = macAddr
+ res.Ref = ref
+ res.EnableDHCP = enableDHCP
+
+ return res
+}
+
+type HostRecordIpv6Addr struct {
+ IBBase `json:"-"`
+ Ipv6Addr string `json:"ipv6addr,omitempty"`
+ Ref string `json:"_ref,omitempty"`
+ Duid string `json:"duid,omitempty"`
+ View string `json:"view,omitempty"`
+ Cidr string `json:"network,omitempty"`
+ EnableDHCP *bool `json:"configure_for_dhcp,omitempty"`
+}
+
+func NewEmptyHostRecordIpv6Addr() *HostRecordIpv6Addr {
+ res := &HostRecordIpv6Addr{}
+ res.objectType = "record:host_ipv6addr"
+
+ return res
+}
+
+func NewHostRecordIpv6Addr(
+ ipAddr string,
+ duid string,
+ enableDHCP *bool,
+ ref string) *HostRecordIpv6Addr {
+
+ res := NewEmptyHostRecordIpv6Addr()
+ res.Ipv6Addr = ipAddr
+ res.Duid = duid
+ res.Ref = ref
+ res.EnableDHCP = enableDHCP
+
+ return res
}
type HostRecord struct {
@@ -431,20 +565,61 @@ type HostRecord struct {
Ref string `json:"_ref,omitempty"`
Ipv4Addr string `json:"ipv4addr,omitempty"`
Ipv4Addrs []HostRecordIpv4Addr `json:"ipv4addrs,omitempty"`
+ Ipv6Addr string `json:"ipv6addr,omitempty"`
+ Ipv6Addrs []HostRecordIpv6Addr `json:"ipv6addrs,omitempty"`
Name string `json:"name,omitempty"`
View string `json:"view,omitempty"`
Zone string `json:"zone,omitempty"`
EnableDns *bool `json:"configure_for_dns,omitempty"`
NetworkView string `json:"network_view,omitempty"`
- Ea EA `json:"extattrs,omitempty"`
+ Comment string `json:"comment"`
+ Ea EA `json:"extattrs"`
+ Aliases []string `json:"aliases,omitempty"`
}
-func NewHostRecord(rh HostRecord) *HostRecord {
- res := rh
+func NewEmptyHostRecord() *HostRecord {
+ res := &HostRecord{}
res.objectType = "record:host"
- res.returnFields = []string{"extattrs", "ipv4addrs", "name", "view", "zone"}
+ res.returnFields = []string{"extattrs", "ipv4addrs", "ipv6addrs", "name", "view", "zone", "comment", "network_view", "aliases"}
+
+ return res
+}
+
+func NewHostRecord(
+ netView string,
+ name string,
+ ipv4Addr string,
+ ipv6Addr string,
+ ipv4AddrList []HostRecordIpv4Addr,
+ ipv6AddrList []HostRecordIpv6Addr,
+ eas EA,
+ enableDNS *bool,
+ dnsView string,
+ zone string,
+ ref string,
+ comment string,
+ aliases []string) *HostRecord {
+
+ res := NewEmptyHostRecord()
+ res.NetworkView = netView
+ res.Name = name
+ res.Ea = eas
+ res.View = dnsView
+ res.Zone = zone
+ res.Ref = ref
+ res.Comment = comment
+ res.Ipv4Addr = ipv4Addr
+ res.Ipv6Addr = ipv6Addr
+ res.Ipv4Addrs = ipv4AddrList
+ res.Ipv6Addrs = ipv6AddrList
+ res.Aliases = aliases
+
+ if enableDNS != nil {
+ res.EnableDns = new(bool)
+ *res.EnableDns = *enableDNS
+ }
- return &res
+ return res
}
type RecordTXT struct {
@@ -455,7 +630,7 @@ type RecordTXT struct {
TTL int `json:"ttl,omitempty"`
View string `json:"view,omitempty"`
Zone string `json:"zone,omitempty"`
- Ea EA `json:"extattrs,omitempty"`
+ Ea EA `json:"extattrs"`
}
func NewRecordTXT(rt RecordTXT) *RecordTXT {
@@ -471,7 +646,7 @@ type ZoneAuth struct {
Ref string `json:"_ref,omitempty"`
Fqdn string `json:"fqdn,omitempty"`
View string `json:"view,omitempty"`
- Ea EA `json:"extattrs,omitempty"`
+ Ea EA `json:"extattrs"`
}
func NewZoneAuth(za ZoneAuth) *ZoneAuth {
@@ -493,7 +668,7 @@ type ZoneDelegated struct {
Fqdn string `json:"fqdn,omitempty"`
DelegateTo []NameServer `json:"delegate_to,omitempty"`
View string `json:"view,omitempty"`
- Ea EA `json:"extattrs,omitempty"`
+ Ea EA `json:"extattrs"`
}
func NewZoneDelegated(za ZoneDelegated) *ZoneDelegated {