You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cloudstack.apache.org by su...@apache.org on 2026/08/17 09:20:35 UTC

(cloudstack-terraform-provider) branch main updated: Declarative storage network IP range (#299)

This is an automated email from the ASF dual-hosted git repository.

sureshanaparti pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/cloudstack-terraform-provider.git


The following commit(s) were added to refs/heads/main by this push:
     new ca078cc  Declarative storage network IP range (#299)
ca078cc is described below

commit ca078cc21ec27b1290b3eed1691ac929f67a5843
Author: bddvlpr <lu...@bddvlpr.com>
AuthorDate: Mon Aug 17 11:20:29 2026 +0200

    Declarative storage network IP range (#299)
---
 cloudstack/provider.go                             |   1 +
 ...resource_cloudstack_storage_network_ip_range.go | 169 +++++++++++++++++++++
 ...rce_cloudstack_storage_network_ip_range_test.go | 154 +++++++++++++++++++
 website/cloudstack.erb                             |   4 +
 .../docs/r/storage_network_ip_range.html.markdown  |  56 +++++++
 5 files changed, 384 insertions(+)

diff --git a/cloudstack/provider.go b/cloudstack/provider.go
index 4eba442..0e0ee80 100644
--- a/cloudstack/provider.go
+++ b/cloudstack/provider.go
@@ -146,6 +146,7 @@ func Provider() *schema.Provider {
 			"cloudstack_ssh_keypair":                    resourceCloudStackSSHKeyPair(),
 			"cloudstack_static_nat":                     resourceCloudStackStaticNAT(),
 			"cloudstack_static_route":                   resourceCloudStackStaticRoute(),
+			"cloudstack_storage_network_ip_range":       resourceCloudStackStorageNetworkIpRange(),
 			"cloudstack_storage_pool":                   resourceCloudStackStoragePool(),
 			"cloudstack_template":                       resourceCloudStackTemplate(),
 			"cloudstack_traffic_type":                   resourceCloudStackTrafficType(),
diff --git a/cloudstack/resource_cloudstack_storage_network_ip_range.go b/cloudstack/resource_cloudstack_storage_network_ip_range.go
new file mode 100644
index 0000000..709108d
--- /dev/null
+++ b/cloudstack/resource_cloudstack_storage_network_ip_range.go
@@ -0,0 +1,169 @@
+//
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+//
+
+package cloudstack
+
+import (
+	"fmt"
+	"log"
+
+	"github.com/apache/cloudstack-go/v2/cloudstack"
+	"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
+)
+
+func resourceCloudStackStorageNetworkIpRange() *schema.Resource {
+	return &schema.Resource{
+		Create: resourceCloudStackStorageNetworkIpRangeCreate,
+		Read:   resourceCloudStackStorageNetworkIpRangeRead,
+		Update: resourceCloudStackStorageNetworkIpRangeUpdate,
+		Delete: resourceCloudStackStorageNetworkIpRangeDelete,
+		Importer: &schema.ResourceImporter{
+			State: schema.ImportStatePassthrough,
+		},
+		Schema: map[string]*schema.Schema{
+			"gateway": {
+				Description: "the gateway for the storage network IP range",
+				Type:        schema.TypeString,
+				Required:    true,
+				ForceNew:    true,
+			},
+			"netmask": {
+				Description: "the netmask for the storage network IP range",
+				Type:        schema.TypeString,
+				Required:    true,
+			},
+			"pod_id": {
+				Description: "the Pod ID for the storage network IP range",
+				Type:        schema.TypeString,
+				Required:    true,
+				ForceNew:    true,
+			},
+			"start_ip": {
+				Description: "the beginning IP address in the storage network IP range",
+				Type:        schema.TypeString,
+				Required:    true,
+			},
+			"end_ip": {
+				Description: "the ending IP address in the storage network IP range",
+				Type:        schema.TypeString,
+				Optional:    true,
+				Computed:    true,
+			},
+			"vlan": {
+				Description: "the optional VLAN of the storage network IP range",
+				Type:        schema.TypeInt,
+				Optional:    true,
+			},
+			"network_id": {
+				Description: "the network id of the storage network IP range",
+				Type:        schema.TypeString,
+				Computed:    true,
+			},
+		},
+	}
+}
+
+func resourceCloudStackStorageNetworkIpRangeCreate(d *schema.ResourceData, meta interface{}) error {
+	cs := meta.(*cloudstack.CloudStackClient)
+
+	p := cs.Network.NewCreateStorageNetworkIpRangeParams(
+		d.Get("gateway").(string),
+		d.Get("netmask").(string),
+		d.Get("pod_id").(string),
+		d.Get("start_ip").(string),
+	)
+
+	if v, ok := d.GetOk("end_ip"); ok {
+		p.SetEndip(v.(string))
+	}
+	if v, ok := d.GetOk("vlan"); ok {
+		p.SetVlan(v.(int))
+	}
+
+	r, err := cs.Network.CreateStorageNetworkIpRange(p)
+	if err != nil {
+		return fmt.Errorf("Error creating storage network IP range: %s", err)
+	}
+
+	d.SetId(r.Id)
+
+	return resourceCloudStackStorageNetworkIpRangeRead(d, meta)
+}
+
+func resourceCloudStackStorageNetworkIpRangeRead(d *schema.ResourceData, meta interface{}) error {
+	cs := meta.(*cloudstack.CloudStackClient)
+
+	r, count, err := cs.Network.GetStorageNetworkIpRangeByID(d.Id())
+	if err != nil {
+		if count == 0 {
+			log.Printf("[DEBUG] Storage network IP range %s does no longer exist", d.Id())
+			d.SetId("")
+			return nil
+		}
+
+		return err
+	}
+
+	d.Set("gateway", r.Gateway)
+	d.Set("netmask", r.Netmask)
+	d.Set("pod_id", r.Podid)
+	d.Set("start_ip", r.Startip)
+	d.Set("end_ip", r.Endip)
+	d.Set("vlan", r.Vlan)
+	d.Set("network_id", r.Networkid)
+
+	return nil
+}
+
+func resourceCloudStackStorageNetworkIpRangeUpdate(d *schema.ResourceData, meta interface{}) error {
+	cs := meta.(*cloudstack.CloudStackClient)
+
+	p := cs.Network.NewUpdateStorageNetworkIpRangeParams(d.Id())
+
+	if v, ok := d.GetOk("netmask"); ok {
+		p.SetNetmask(v.(string))
+	}
+	if v, ok := d.GetOk("start_ip"); ok {
+		p.SetStartip(v.(string))
+	}
+	if v, ok := d.GetOk("end_ip"); ok {
+		p.SetEndip(v.(string))
+	}
+	if v, ok := d.GetOk("vlan"); ok {
+		p.SetVlan(v.(int))
+	}
+
+	_, err := cs.Network.UpdateStorageNetworkIpRange(p)
+	if err != nil {
+		return fmt.Errorf("Error updating storage network IP range: %s", err)
+	}
+
+	return resourceCloudStackStorageNetworkIpRangeRead(d, meta)
+}
+
+func resourceCloudStackStorageNetworkIpRangeDelete(d *schema.ResourceData, meta interface{}) error {
+	cs := meta.(*cloudstack.CloudStackClient)
+
+	_, err := cs.Network.DeleteStorageNetworkIpRange(cs.Network.NewDeleteStorageNetworkIpRangeParams(d.Id()))
+	if err != nil {
+		return fmt.Errorf("Error deleting storage network IP range: %s", err)
+	}
+
+	return nil
+}
diff --git a/cloudstack/resource_cloudstack_storage_network_ip_range_test.go b/cloudstack/resource_cloudstack_storage_network_ip_range_test.go
new file mode 100644
index 0000000..f8c833a
--- /dev/null
+++ b/cloudstack/resource_cloudstack_storage_network_ip_range_test.go
@@ -0,0 +1,154 @@
+//
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+//
+
+package cloudstack
+
+import (
+	"testing"
+
+	"github.com/hashicorp/terraform-plugin-testing/helper/resource"
+)
+
+func TestAccCloudStackStorageNetworkIpRange_basic(t *testing.T) {
+	resource.Test(t, resource.TestCase{
+		PreCheck:  func() { testAccPreCheck(t) },
+		Providers: testAccProviders,
+		Steps: []resource.TestStep{
+			{
+				Config: testAccCloudStackStorageNetworkIpRange_basic,
+				Check: resource.ComposeTestCheckFunc(
+					resource.TestCheckResourceAttr("cloudstack_storage_network_ip_range.test", "gateway", "10.1.1.1"),
+					resource.TestCheckResourceAttr("cloudstack_storage_network_ip_range.test", "netmask", "255.255.255.0"),
+					resource.TestCheckResourceAttr("cloudstack_storage_network_ip_range.test", "start_ip", "10.1.1.2"),
+					resource.TestCheckResourceAttr("cloudstack_storage_network_ip_range.test", "end_ip", "10.1.1.10"),
+					resource.TestCheckResourceAttr("cloudstack_storage_network_ip_range.test", "vlan", "100"),
+				),
+			},
+			{
+				Config: testAccCloudStackStorageNetworkIpRange_update,
+				Check: resource.ComposeTestCheckFunc(
+					resource.TestCheckResourceAttr("cloudstack_storage_network_ip_range.test", "gateway", "10.1.1.1"),
+					resource.TestCheckResourceAttr("cloudstack_storage_network_ip_range.test", "netmask", "255.255.255.0"),
+					resource.TestCheckResourceAttr("cloudstack_storage_network_ip_range.test", "start_ip", "10.1.1.20"),
+					resource.TestCheckResourceAttr("cloudstack_storage_network_ip_range.test", "end_ip", "10.1.1.30"),
+					resource.TestCheckResourceAttr("cloudstack_storage_network_ip_range.test", "vlan", "100"),
+				),
+			},
+		},
+	})
+}
+
+func TestAccCloudStackStorageNetworkIpRange_noVlan(t *testing.T) {
+	resource.Test(t, resource.TestCase{
+		PreCheck:  func() { testAccPreCheck(t) },
+		Providers: testAccProviders,
+		Steps: []resource.TestStep{
+			{
+				Config: testAccCloudStackStorageNetworkIpRange_noVlan,
+				Check: resource.ComposeTestCheckFunc(
+					resource.TestCheckResourceAttr("cloudstack_storage_network_ip_range.test", "start_ip", "10.1.1.2"),
+					resource.TestCheckResourceAttr("cloudstack_storage_network_ip_range.test", "end_ip", "10.1.1.10"),
+				),
+			},
+		},
+	})
+}
+
+const testAccCloudStackStorageNetworkIpRange_basic = `
+resource "cloudstack_zone" "test" {
+	name          = "acctest"
+	dns1          = "8.8.8.8"
+	dns2          = "8.8.8.8"
+	internal_dns1 = "8.8.4.4"
+	internal_dns2 = "8.8.4.4"
+	network_type  = "Advanced"
+	domain        = "cloudstack.apache.org"
+}
+resource "cloudstack_pod" "test" {
+	name             = "acctestpod"
+	allocation_state = "Enabled"
+	zone_id  = cloudstack_zone.test.id
+	gateway  = "10.0.0.1"
+	netmask  = "255.255.255.0"
+	start_ip = "10.0.0.2"
+}
+resource "cloudstack_storage_network_ip_range" "test" {
+	pod_id   = cloudstack_pod.test.id
+	gateway  = "10.1.1.1"
+	netmask  = "255.255.255.0"
+	start_ip = "10.1.1.2"
+	end_ip   = "10.1.1.10"
+	vlan     = 100
+}
+`
+
+const testAccCloudStackStorageNetworkIpRange_update = `
+resource "cloudstack_zone" "test" {
+	name          = "acctest"
+	dns1          = "8.8.8.8"
+	dns2          = "8.8.8.8"
+	internal_dns1 = "8.8.4.4"
+	internal_dns2 = "8.8.4.4"
+	network_type  = "Advanced"
+	domain        = "cloudstack.apache.org"
+}
+resource "cloudstack_pod" "test" {
+	name             = "acctestpod"
+	allocation_state = "Enabled"
+	zone_id  = cloudstack_zone.test.id
+	gateway  = "10.0.0.1"
+	netmask  = "255.255.255.0"
+	start_ip = "10.0.0.2"
+}
+resource "cloudstack_storage_network_ip_range" "test" {
+	pod_id   = cloudstack_pod.test.id
+	gateway  = "10.1.1.1"
+	netmask  = "255.255.255.0"
+	start_ip = "10.1.1.20"
+	end_ip   = "10.1.1.30"
+	vlan     = 100
+}
+`
+
+const testAccCloudStackStorageNetworkIpRange_noVlan = `
+resource "cloudstack_zone" "test" {
+	name          = "acctest"
+	dns1          = "8.8.8.8"
+	dns2          = "8.8.8.8"
+	internal_dns1 = "8.8.4.4"
+	internal_dns2 = "8.8.4.4"
+	network_type  = "Advanced"
+	domain        = "cloudstack.apache.org"
+}
+resource "cloudstack_pod" "test" {
+	name             = "acctestpod"
+	allocation_state = "Enabled"
+	zone_id  = cloudstack_zone.test.id
+	gateway  = "10.0.0.1"
+	netmask  = "255.255.255.0"
+	start_ip = "10.0.0.2"
+}
+resource "cloudstack_storage_network_ip_range" "test" {
+	pod_id   = cloudstack_pod.test.id
+	gateway  = "10.1.1.1"
+	netmask  = "255.255.255.0"
+	start_ip = "10.1.1.2"
+	end_ip   = "10.1.1.10"
+}
+`
diff --git a/website/cloudstack.erb b/website/cloudstack.erb
index 06b6a7c..09d14d9 100644
--- a/website/cloudstack.erb
+++ b/website/cloudstack.erb
@@ -109,6 +109,10 @@
                             <a href="/docs/providers/cloudstack/r/static_route.html">cloudstack_static_route</a>
                         </li>
 
+                        <li<%= sidebar_current("docs-cloudstack-resource-storage-network-ip-range") %>>
+                            <a href="/docs/providers/cloudstack/r/storage_network_ip_range.html">cloudstack_storage_network_ip_range</a>
+                        </li>
+
                         <li<%= sidebar_current("docs-cloudstack-resource-template") %>>
                             <a href="/docs/providers/cloudstack/r/template.html">cloudstack_template</a>
                         </li>
diff --git a/website/docs/r/storage_network_ip_range.html.markdown b/website/docs/r/storage_network_ip_range.html.markdown
new file mode 100644
index 0000000..9deb789
--- /dev/null
+++ b/website/docs/r/storage_network_ip_range.html.markdown
@@ -0,0 +1,56 @@
+---
+layout: "cloudstack"
+page_title: "CloudStack: cloudstack_storage_network_ip_range"
+sidebar_current: "docs-cloudstack-resource-storage-network-ip-range"
+description: |-
+  Creates a storage network IP range.
+---
+
+# cloudstack_storage_network_ip_range
+
+Creates a storage network IP range for a pod.
+
+## Example Usage
+
+Basic usage:
+
+```hcl
+resource "cloudstack_storage_network_ip_range" "default" {
+    pod_id   = cloudstack_pod.default.id
+    gateway  = "10.1.1.1"
+    netmask  = "255.255.255.0"
+    start_ip = "10.1.1.2"
+    end_ip   = "10.1.1.10"
+    vlan     = 100
+}
+```
+
+## Argument Reference
+
+The following arguments are supported:
+
+- `pod_id` - (Required) The Pod ID for the storage network IP range. Changing
+  this forces a new resource to be created.
+- `gateway` - (Required) The gateway for the storage network IP range. Changing
+  this forces a new resource to be created.
+- `netmask` - (Required) The netmask for the storage network IP range.
+- `start_ip` - (Required) The beginning IP address in the storage network IP range.
+- `end_ip` - (Optional) The ending IP address in the storage network IP range.
+- `vlan` - (Optional) The optional VLAN of the storage network IP range.
+
+## Attributes Reference
+
+The following attributes are exported:
+
+- `id` - The ID of the storage network IP range.
+- `end_ip` - The ending IP address in the storage network IP range.
+- `network_id` - The network ID of the storage network IP range.
+
+## Import
+
+Storage network IP ranges can be imported; use `<ID>` as the import ID. For
+example:
+
+```shell
+terraform import cloudstack_storage_network_ip_range.default 5cf69677-7e4b-4bf4-b868-f0b02bb72ee0
+```