Skip to content

Commit

Permalink
✨ Implement dhcp_relay resource
Browse files Browse the repository at this point in the history
  • Loading branch information
riege-burghardt authored and twink0r committed Apr 1, 2022
1 parent 0de1eeb commit 98200e4
Show file tree
Hide file tree
Showing 3 changed files with 243 additions and 0 deletions.
1 change: 1 addition & 0 deletions panos/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,7 @@ func Provider() terraform.ResourceProvider {
"panos_custom_url_category_entry": resourceCustomUrlCategoryEntry(),
"panos_data_filtering_security_profile": resourceDataFilteringSecurityProfile(),
"panos_decryption_rule_group": resourceDecryptionRuleGroup(),
"panos_dhcp_relay": resourceDhcpRelay(),
"panos_dos_protection_profile": resourceDosProtectionProfile(),
"panos_dynamic_user_group": resourceDynamicUserGroup(),
"panos_file_blocking_security_profile": resourceFileBlockingSecurityProfile(),
Expand Down
203 changes: 203 additions & 0 deletions panos/resource_dhcp_relay.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,203 @@
package panos

import (
"fmt"

"github.com/PaloAltoNetworks/pango"
"github.com/PaloAltoNetworks/pango/netw/dhcp"

"github.com/hashicorp/terraform-plugin-sdk/helper/resource"
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
)

func resourceDhcpRelay() *schema.Resource {
return &schema.Resource{
Create: createDhcpRelay,
Read: readDhcpRelay,
Update: updateDhcpRelay,
Delete: deleteDhcpRelay,

Importer: &schema.ResourceImporter{
State: schema.ImportStatePassthrough,
},

Schema: map[string]*schema.Schema{
"name": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
Description: "Interface to enable dhcp relay on",
},
"vsys": {
Type: schema.TypeString,
Optional: true,
Default: "vsys1",
ForceNew: true,
Description: "Vsys to put interface in",
},
"ipv4_enabled": {
Type: schema.TypeBool,
Optional: true,
Description: "Enables dhcp relay for ipv4",
},
"ipv6_enabled": {
Type: schema.TypeBool,
Optional: true,
Description: "Enables dhcp relay for ipv6",
},
"ipv4_servers": {
Type: schema.TypeList,
Optional: true,
Elem: &schema.Schema{
Type: schema.TypeString,
},
Description: "List of ipv4 dhcp servers",
},
"ipv6_servers": {
Type: schema.TypeList,
Optional: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"server": {
Type: schema.TypeString,
Optional: true,
},
"interface": {
Type: schema.TypeString,
Optional: true,
},
},
Description: "List of ipv6 dhcp servers",
},
},
},
}
}

func parseDhcpRelay(d *schema.ResourceData) (string, dhcp.Entry) {
vsys := d.Get("vsys").(string)

if !castIntoBool(d.Get("ipv4_enabled")) && !castIntoBool(d.Get("ipv6_enabled")) {
return "", dhcp.Entry{}
}

o := dhcp.Entry{
Name: d.Get("name").(string),

Relay: &dhcp.Relay{
Ipv4Enabled: castIntoBool(d.Get("ipv4_enabled")),
Ipv4Servers: flattenIPv4DhcpServers(d.Get("ipv4_servers")),
Ipv6Enabled: castIntoBool(d.Get("ipv6_enabled")),
Ipv6Servers: flattenIPv6DhcpServers(d.Get("ipv6_servers")),
},
}

return vsys, o
}

func castIntoBool(v interface{}) bool {
return v.(bool)
}

func flattenIPv4DhcpServers(o interface{}) []string {
var d []string
for _, v := range o.([]interface{}) {
d = append(d, v.(string))
}
return d
}

func flattenIPv6DhcpServers(d interface{}) []dhcp.Ipv6Server {
var o []dhcp.Ipv6Server
for _, v := range d.([]interface{}) {
m := v.(map[string]interface{})
o = append(o, dhcp.Ipv6Server{
Server: m["server"].(string),
Interface: m["interface"].(string),
})
}
return o
}

func isEmpty(o dhcp.Entry) bool {
return !o.Relay.Ipv4Enabled && !o.Relay.Ipv6Enabled && len(o.Relay.Ipv4Servers) ==0 && len(o.Relay.Ipv6Servers) == 0
}

func readDhcpRelay(d *schema.ResourceData, meta interface{}) error {
var err error

fw := meta.(*pango.Firewall)
name := d.Get("name").(string)

o, err := fw.Network.Dhcp.Get(name)
if err != nil {
if isObjectNotFound(err) {
d.SetId("")
return nil
}
return err
}

d.Set("name", o.Name)
d.Set("ipv4_enabled", o.Relay.Ipv4Enabled)
d.Set("ipv6_enabled", o.Relay.Ipv6Enabled)
d.Set("ipv4_servers", o.Relay.Ipv6Enabled)
d.Set("ipv6_servers", o.Relay.Ipv6Servers)

return nil
}

func createDhcpRelay(d *schema.ResourceData, meta interface{}) error {
fw := meta.(*pango.Firewall)
vsys, o := parseDhcpRelay(d)

if vsys == "" && isEmpty(o) {
return fmt.Errorf("[ERROR] Error in creating DHCP relay: no valid configuration provided")
}

if err := fw.Network.Dhcp.Set(o); err != nil {
return err
}

d.SetId(resource.UniqueId())
return d.Set("vsys", vsys)
}

func updateDhcpRelay(d *schema.ResourceData, meta interface{}) error {
var err error

fw := meta.(*pango.Firewall)
name := d.Get("name").(string)

dg, err := fw.Network.Dhcp.Get(name)
if err != nil {
return err
}

vsys, o := parseDhcpRelay(d)

if vsys == "" && isEmpty(o) {
return fmt.Errorf("[ERROR] Error in updating DHCP relay: no valid configuration provided")
}

dg.Copy(o)
if err = fw.Network.Dhcp.Edit(o); err != nil {
return err
}

return readDhcpRelay(d, meta)
}

func deleteDhcpRelay(d *schema.ResourceData, meta interface{}) error {
fw := meta.(*pango.Firewall)
name := d.Get("name").(string)

err := fw.Network.Dhcp.Delete(name)
if err != nil {
if isObjectNotFound(err) {
return err
}
}
d.SetId("")
return nil
}
39 changes: 39 additions & 0 deletions panos/resource_dhcp_relay_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package panos

import (
"fmt"
"testing"

"github.com/hashicorp/terraform-plugin-sdk/helper/resource"
)

func TestAccPanosDhcpRelay_basic(t *testing.T) {
if !testAccIsFirewall {
t.Skip(SkipFirewallAccTest)
}

resource.Test(t, resource.TestCase{
PreCheck: func() {
testAccPreCheck(t)
},
Providers: testAccProviders,

Steps: []resource.TestStep{
{
Config: fmt.Sprintf(`
resource "panos_dhcp_relay" "test" {
name = "test-eth0"
ipv4_enabled = true
ipv4_servers = [
"10.1.0.1",
"10.2.0.1",
]
}`),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr("panos_dhcp_relay.test", "name", "test-eth0"),
resource.TestCheckResourceAttr("panos_dhcp_relay.ipv4_servers", "#", "2"),
),
},
},
})
}

0 comments on commit 98200e4

Please sign in to comment.