dmacvicar / terraform-provider-libvirt

Terraform provider to provision infrastructure with Linux's KVM using libvirt
Apache License 2.0
1.54k stars 457 forks source link

keyword dnsmasq_options cannot be given #914

Open The-Loeki opened 2 years ago

The-Loeki commented 2 years ago

Lots of DNSmasq options come as keywords only, but dnsmasq_options currently renders option_name=option_value.

  dnsmasq_options {
    dynamic options {
      for_each = ["dnssec", "dnssec-check-unsigned"]
      content {
        option_name = options.value
      }
    }

Renders

2021-12-12T16:45:33.069Z [DEBUG] provider.terraform-provider-libvirt_v0.6.11:       <options xmlns="http://libvirt.org/schemas/network/dnsmasq/1.0">
2021-12-12T16:45:33.069Z [DEBUG] provider.terraform-provider-libvirt_v0.6.11:           <option value="dnssec="></option>
2021-12-12T16:45:33.069Z [DEBUG] provider.terraform-provider-libvirt_v0.6.11:           <option value="dnssec-check-unsigned="></option>
2021-12-12T16:45:33.069Z [DEBUG] provider.terraform-provider-libvirt_v0.6.11:           <option value="conf-file=/usr/share/dnsmasq/trust-anchors.conf"></option>
2021-12-12T16:45:33.069Z [DEBUG] provider.terraform-provider-libvirt_v0.6.11:       </options>
2021-12-12T16:45:33.069Z [DEBUG] provider.terraform-provider-libvirt_v0.6.11:   </network>

which dnsmasq doesnt like

│ Error: Error creating libvirt network: internal error: Child process (VIR_BRIDGE_NAME=network /usr/sbin/dnsmasq --conf-file=/var/lib/libvirt/dnsmasq/net-network.conf --leasefile-ro --dhcp-script=/usr/libexec/libvirt_leaseshelper) unexpected exit status 1: 
│ dnsmasq: extraneous parameter at line 21 of /var/lib/libvirt/dnsmasq/net-network.conf
│ 
│ 
│   with module.cluster.libvirt_network.network,
│   on ../../modules/libvirt-cluster/bootstrap.tf line 15, in resource "libvirt_network" "network":
│   15: resource libvirt_network network {
│ 
╵

But = is hardcoded in: https://github.com/dmacvicar/terraform-provider-libvirt/blob/06d383abe97b94603edb6fd68f318ad1b3ad4685/libvirt/network.go#L192

The-Loeki commented 2 years ago

Workaround XSLT:

resource libvirt_network network {
  name      = "net-${var.name}"

   dnsmasq_options {
    dynamic options {
      for_each = {
        conf-file = "/usr/share/dnsmasq/trust-anchors.conf"
        dns-forward-max = 1024
      }
      content {
        option_name = options.key
        option_value = options.value
      }
    }
  }

  # Workaround for https://github.com/dmacvicar/terraform-provider-libvirt/issues/914
  xml {
    xslt = templatefile("${path.module}/tpl/dnsmasq.xsl", {options=["dnssec", "dnssec-check-unsigned"]})
  }

}
<?xml version="1.0"?>
<xsl:stylesheet version="1.0"
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:dnsmasq="http://libvirt.org/schemas/network/dnsmasq/1.0">
  <xsl:output omit-xml-declaration="yes" indent="yes"/>
  <xsl:template match="node()|@*">
      <xsl:copy>
         <xsl:apply-templates select="node()|@*"/>
      </xsl:copy>
   </xsl:template>

  <xsl:template match="/network/dnsmasq:options">
    <xsl:copy>
        <xsl:apply-templates select="node()|@*"/>
        %{ for option in options ~}        
            <xsl:element name="dnsmasq:option">
                <xsl:attribute name="value">${option}</xsl:attribute>
            </xsl:element>
        %{ endfor ~}            
    </xsl:copy>
  </xsl:template>

</xsl:stylesheet>
agorgl commented 2 years ago

Stumbled into this too trying to pass bind-interfaces option