852 lines
23 KiB
Go
852 lines
23 KiB
Go
|
package cobbler
|
||
|
|
||
|
import (
|
||
|
"bytes"
|
||
|
"fmt"
|
||
|
"log"
|
||
|
"sync"
|
||
|
|
||
|
"github.com/hashicorp/terraform/helper/hashcode"
|
||
|
"github.com/hashicorp/terraform/helper/schema"
|
||
|
cobbler "github.com/jtopjian/cobblerclient"
|
||
|
)
|
||
|
|
||
|
var systemSyncLock sync.Mutex
|
||
|
|
||
|
func resourceSystem() *schema.Resource {
|
||
|
return &schema.Resource{
|
||
|
Create: resourceSystemCreate,
|
||
|
Read: resourceSystemRead,
|
||
|
Update: resourceSystemUpdate,
|
||
|
Delete: resourceSystemDelete,
|
||
|
|
||
|
Schema: map[string]*schema.Schema{
|
||
|
"boot_files": &schema.Schema{
|
||
|
Type: schema.TypeString,
|
||
|
Optional: true,
|
||
|
Computed: true,
|
||
|
},
|
||
|
|
||
|
"comment": &schema.Schema{
|
||
|
Type: schema.TypeString,
|
||
|
Optional: true,
|
||
|
Computed: true,
|
||
|
},
|
||
|
|
||
|
"enable_gpxe": &schema.Schema{
|
||
|
Type: schema.TypeBool,
|
||
|
Optional: true,
|
||
|
Computed: true,
|
||
|
},
|
||
|
|
||
|
"fetchable_files": &schema.Schema{
|
||
|
Type: schema.TypeString,
|
||
|
Optional: true,
|
||
|
Computed: true,
|
||
|
},
|
||
|
|
||
|
"gateway": &schema.Schema{
|
||
|
Type: schema.TypeString,
|
||
|
Optional: true,
|
||
|
Computed: true,
|
||
|
},
|
||
|
|
||
|
"hostname": &schema.Schema{
|
||
|
Type: schema.TypeString,
|
||
|
Optional: true,
|
||
|
Computed: true,
|
||
|
},
|
||
|
|
||
|
"image": &schema.Schema{
|
||
|
Type: schema.TypeString,
|
||
|
Optional: true,
|
||
|
Computed: true,
|
||
|
},
|
||
|
|
||
|
"interface": &schema.Schema{
|
||
|
Type: schema.TypeSet,
|
||
|
Optional: true,
|
||
|
Computed: true,
|
||
|
Elem: &schema.Resource{
|
||
|
Schema: map[string]*schema.Schema{
|
||
|
"name": &schema.Schema{
|
||
|
Type: schema.TypeString,
|
||
|
Required: true,
|
||
|
},
|
||
|
|
||
|
"cnames": &schema.Schema{
|
||
|
Type: schema.TypeList,
|
||
|
Optional: true,
|
||
|
Computed: true,
|
||
|
Elem: &schema.Schema{Type: schema.TypeString},
|
||
|
},
|
||
|
|
||
|
"dhcp_tag": &schema.Schema{
|
||
|
Type: schema.TypeString,
|
||
|
Optional: true,
|
||
|
Computed: true,
|
||
|
},
|
||
|
|
||
|
"dns_name": &schema.Schema{
|
||
|
Type: schema.TypeString,
|
||
|
Optional: true,
|
||
|
Computed: true,
|
||
|
},
|
||
|
|
||
|
"bonding_opts": &schema.Schema{
|
||
|
Type: schema.TypeString,
|
||
|
Optional: true,
|
||
|
Computed: true,
|
||
|
},
|
||
|
|
||
|
"bridge_opts": &schema.Schema{
|
||
|
Type: schema.TypeString,
|
||
|
Optional: true,
|
||
|
Computed: true,
|
||
|
},
|
||
|
|
||
|
"gateway": &schema.Schema{
|
||
|
Type: schema.TypeString,
|
||
|
Optional: true,
|
||
|
Computed: true,
|
||
|
},
|
||
|
|
||
|
"interface_type": &schema.Schema{
|
||
|
Type: schema.TypeString,
|
||
|
Optional: true,
|
||
|
Computed: true,
|
||
|
},
|
||
|
|
||
|
"interface_master": &schema.Schema{
|
||
|
Type: schema.TypeString,
|
||
|
Optional: true,
|
||
|
Computed: true,
|
||
|
},
|
||
|
|
||
|
"ip_address": &schema.Schema{
|
||
|
Type: schema.TypeString,
|
||
|
Optional: true,
|
||
|
Computed: true,
|
||
|
},
|
||
|
|
||
|
"ipv6_address": &schema.Schema{
|
||
|
Type: schema.TypeString,
|
||
|
Optional: true,
|
||
|
Computed: true,
|
||
|
},
|
||
|
|
||
|
"ipv6_secondaries": &schema.Schema{
|
||
|
Type: schema.TypeList,
|
||
|
Optional: true,
|
||
|
Computed: true,
|
||
|
Elem: &schema.Schema{Type: schema.TypeString},
|
||
|
},
|
||
|
|
||
|
"ipv6_mtu": &schema.Schema{
|
||
|
Type: schema.TypeString,
|
||
|
Optional: true,
|
||
|
Computed: true,
|
||
|
},
|
||
|
|
||
|
"ipv6_static_routes": &schema.Schema{
|
||
|
Type: schema.TypeList,
|
||
|
Optional: true,
|
||
|
Computed: true,
|
||
|
Elem: &schema.Schema{Type: schema.TypeString},
|
||
|
},
|
||
|
|
||
|
"ipv6_default_gateway": &schema.Schema{
|
||
|
Type: schema.TypeString,
|
||
|
Optional: true,
|
||
|
Computed: true,
|
||
|
},
|
||
|
|
||
|
"mac_address": &schema.Schema{
|
||
|
Type: schema.TypeString,
|
||
|
Optional: true,
|
||
|
Computed: true,
|
||
|
},
|
||
|
|
||
|
"management": &schema.Schema{
|
||
|
Type: schema.TypeBool,
|
||
|
Optional: true,
|
||
|
Computed: true,
|
||
|
},
|
||
|
|
||
|
"netmask": &schema.Schema{
|
||
|
Type: schema.TypeString,
|
||
|
Optional: true,
|
||
|
Computed: true,
|
||
|
},
|
||
|
|
||
|
"static": &schema.Schema{
|
||
|
Type: schema.TypeBool,
|
||
|
Optional: true,
|
||
|
Computed: true,
|
||
|
},
|
||
|
|
||
|
"static_routes": &schema.Schema{
|
||
|
Type: schema.TypeList,
|
||
|
Optional: true,
|
||
|
Computed: true,
|
||
|
Elem: &schema.Schema{Type: schema.TypeString},
|
||
|
},
|
||
|
|
||
|
"virt_bridge": &schema.Schema{
|
||
|
Type: schema.TypeString,
|
||
|
Optional: true,
|
||
|
Computed: true,
|
||
|
},
|
||
|
},
|
||
|
},
|
||
|
Set: resourceSystemInterfaceHash,
|
||
|
},
|
||
|
|
||
|
"ipv6_default_device": &schema.Schema{
|
||
|
Type: schema.TypeString,
|
||
|
Optional: true,
|
||
|
Computed: true,
|
||
|
},
|
||
|
|
||
|
"kernel_options": &schema.Schema{
|
||
|
Type: schema.TypeString,
|
||
|
Optional: true,
|
||
|
Computed: true,
|
||
|
},
|
||
|
|
||
|
"kernel_options_post": &schema.Schema{
|
||
|
Type: schema.TypeString,
|
||
|
Optional: true,
|
||
|
Computed: true,
|
||
|
},
|
||
|
|
||
|
"kickstart": &schema.Schema{
|
||
|
Type: schema.TypeString,
|
||
|
Optional: true,
|
||
|
Computed: true,
|
||
|
},
|
||
|
|
||
|
"ks_meta": &schema.Schema{
|
||
|
Type: schema.TypeString,
|
||
|
Optional: true,
|
||
|
Computed: true,
|
||
|
},
|
||
|
|
||
|
"ldap_enabled": &schema.Schema{
|
||
|
Type: schema.TypeBool,
|
||
|
Optional: true,
|
||
|
Computed: true,
|
||
|
},
|
||
|
|
||
|
"ldap_type": &schema.Schema{
|
||
|
Type: schema.TypeString,
|
||
|
Optional: true,
|
||
|
Computed: true,
|
||
|
},
|
||
|
|
||
|
"mgmt_classes": &schema.Schema{
|
||
|
Type: schema.TypeList,
|
||
|
Optional: true,
|
||
|
Computed: true,
|
||
|
Elem: &schema.Schema{Type: schema.TypeString},
|
||
|
},
|
||
|
|
||
|
"mgmt_parameters": &schema.Schema{
|
||
|
Type: schema.TypeString,
|
||
|
Optional: true,
|
||
|
Computed: true,
|
||
|
},
|
||
|
|
||
|
"monit_enabled": &schema.Schema{
|
||
|
Type: schema.TypeBool,
|
||
|
Optional: true,
|
||
|
Computed: true,
|
||
|
},
|
||
|
|
||
|
"name": &schema.Schema{
|
||
|
Type: schema.TypeString,
|
||
|
Required: true,
|
||
|
ForceNew: true,
|
||
|
},
|
||
|
|
||
|
"name_servers_search": &schema.Schema{
|
||
|
Type: schema.TypeList,
|
||
|
Optional: true,
|
||
|
Computed: true,
|
||
|
Elem: &schema.Schema{Type: schema.TypeString},
|
||
|
},
|
||
|
|
||
|
"name_servers": &schema.Schema{
|
||
|
Type: schema.TypeList,
|
||
|
Optional: true,
|
||
|
Computed: true,
|
||
|
Elem: &schema.Schema{Type: schema.TypeString},
|
||
|
},
|
||
|
|
||
|
"netboot_enabled": &schema.Schema{
|
||
|
Type: schema.TypeBool,
|
||
|
Optional: true,
|
||
|
Computed: true,
|
||
|
},
|
||
|
|
||
|
"owners": &schema.Schema{
|
||
|
Type: schema.TypeList,
|
||
|
Optional: true,
|
||
|
Computed: true,
|
||
|
Elem: &schema.Schema{Type: schema.TypeString},
|
||
|
},
|
||
|
|
||
|
"power_address": &schema.Schema{
|
||
|
Type: schema.TypeString,
|
||
|
Optional: true,
|
||
|
Computed: true,
|
||
|
},
|
||
|
|
||
|
"power_id": &schema.Schema{
|
||
|
Type: schema.TypeString,
|
||
|
Optional: true,
|
||
|
Computed: true,
|
||
|
},
|
||
|
|
||
|
"power_pass": &schema.Schema{
|
||
|
Type: schema.TypeString,
|
||
|
Optional: true,
|
||
|
Computed: true,
|
||
|
},
|
||
|
|
||
|
"power_type": &schema.Schema{
|
||
|
Type: schema.TypeString,
|
||
|
Optional: true,
|
||
|
Computed: true,
|
||
|
},
|
||
|
|
||
|
"power_user": &schema.Schema{
|
||
|
Type: schema.TypeString,
|
||
|
Optional: true,
|
||
|
Computed: true,
|
||
|
},
|
||
|
|
||
|
"profile": &schema.Schema{
|
||
|
Type: schema.TypeString,
|
||
|
Required: true,
|
||
|
},
|
||
|
|
||
|
"proxy": &schema.Schema{
|
||
|
Type: schema.TypeString,
|
||
|
Optional: true,
|
||
|
Computed: true,
|
||
|
},
|
||
|
|
||
|
"redhat_management_key": &schema.Schema{
|
||
|
Type: schema.TypeString,
|
||
|
Optional: true,
|
||
|
Computed: true,
|
||
|
},
|
||
|
|
||
|
"redhat_management_server": &schema.Schema{
|
||
|
Type: schema.TypeString,
|
||
|
Optional: true,
|
||
|
Computed: true,
|
||
|
},
|
||
|
|
||
|
"status": &schema.Schema{
|
||
|
Type: schema.TypeString,
|
||
|
Optional: true,
|
||
|
Computed: true,
|
||
|
},
|
||
|
|
||
|
"template_files": &schema.Schema{
|
||
|
Type: schema.TypeString,
|
||
|
Optional: true,
|
||
|
Computed: true,
|
||
|
},
|
||
|
|
||
|
"template_remote_kickstarts": &schema.Schema{
|
||
|
Type: schema.TypeInt,
|
||
|
Optional: true,
|
||
|
Computed: true,
|
||
|
},
|
||
|
|
||
|
"virt_auto_boot": &schema.Schema{
|
||
|
Type: schema.TypeString,
|
||
|
Optional: true,
|
||
|
Computed: true,
|
||
|
},
|
||
|
|
||
|
"virt_file_size": &schema.Schema{
|
||
|
Type: schema.TypeString,
|
||
|
Optional: true,
|
||
|
Computed: true,
|
||
|
},
|
||
|
|
||
|
"virt_cpus": &schema.Schema{
|
||
|
Type: schema.TypeString,
|
||
|
Optional: true,
|
||
|
Computed: true,
|
||
|
},
|
||
|
|
||
|
"virt_type": &schema.Schema{
|
||
|
Type: schema.TypeString,
|
||
|
Optional: true,
|
||
|
Computed: true,
|
||
|
},
|
||
|
|
||
|
"virt_path": &schema.Schema{
|
||
|
Type: schema.TypeString,
|
||
|
Optional: true,
|
||
|
Computed: true,
|
||
|
},
|
||
|
|
||
|
"virt_pxe_boot": &schema.Schema{
|
||
|
Type: schema.TypeInt,
|
||
|
Optional: true,
|
||
|
Computed: true,
|
||
|
},
|
||
|
|
||
|
"virt_ram": &schema.Schema{
|
||
|
Type: schema.TypeString,
|
||
|
Optional: true,
|
||
|
Computed: true,
|
||
|
},
|
||
|
|
||
|
"virt_disk_driver": &schema.Schema{
|
||
|
Type: schema.TypeString,
|
||
|
Optional: true,
|
||
|
Computed: true,
|
||
|
},
|
||
|
},
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func resourceSystemCreate(d *schema.ResourceData, meta interface{}) error {
|
||
|
systemSyncLock.Lock()
|
||
|
defer systemSyncLock.Unlock()
|
||
|
|
||
|
config := meta.(*Config)
|
||
|
|
||
|
// Create a cobblerclient.System struct
|
||
|
system := buildSystem(d)
|
||
|
|
||
|
// Attempt to create the System
|
||
|
log.Printf("[DEBUG] Cobbler System: Create Options: %#v", system)
|
||
|
newSystem, err := config.cobblerClient.CreateSystem(system)
|
||
|
if err != nil {
|
||
|
return fmt.Errorf("Cobbler System: Error Creating: %s", err)
|
||
|
}
|
||
|
|
||
|
// Build cobblerclient.Interface structs
|
||
|
interfaces := buildSystemInterfaces(d.Get("interface").(*schema.Set))
|
||
|
|
||
|
// Add each interface to the system
|
||
|
for interfaceName, interfaceInfo := range interfaces {
|
||
|
log.Printf("[DEBUG] Cobbler System Interface %#v: %#v", interfaceName, interfaceInfo)
|
||
|
if err := newSystem.CreateInterface(interfaceName, interfaceInfo); err != nil {
|
||
|
return fmt.Errorf("Cobbler System: Error adding Interface %s to %s: %s", interfaceName, newSystem.Name, err)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
log.Printf("[DEBUG] Cobbler System: Created System: %#v", newSystem)
|
||
|
d.SetId(newSystem.Name)
|
||
|
|
||
|
log.Printf("[DEBUG] Cobbler System: syncing system")
|
||
|
if err := config.cobblerClient.Sync(); err != nil {
|
||
|
return fmt.Errorf("Cobbler System: Error syncing system: %s", err)
|
||
|
}
|
||
|
|
||
|
return resourceSystemRead(d, meta)
|
||
|
}
|
||
|
|
||
|
func resourceSystemRead(d *schema.ResourceData, meta interface{}) error {
|
||
|
config := meta.(*Config)
|
||
|
|
||
|
// Retrieve the system entry from Cobbler
|
||
|
system, err := config.cobblerClient.GetSystem(d.Id())
|
||
|
if err != nil {
|
||
|
return fmt.Errorf("Cobbler System: Error Reading (%s): %s", d.Id(), err)
|
||
|
}
|
||
|
|
||
|
// Set all fields
|
||
|
d.Set("boot_files", system.BootFiles)
|
||
|
d.Set("comment", system.Comment)
|
||
|
d.Set("enable_gpxe", system.EnableGPXE)
|
||
|
d.Set("fetchable_files", system.FetchableFiles)
|
||
|
d.Set("gateway", system.Gateway)
|
||
|
d.Set("hostname", system.Hostname)
|
||
|
d.Set("image", system.Image)
|
||
|
d.Set("ipv6_default_device", system.IPv6DefaultDevice)
|
||
|
d.Set("kernel_options", system.KernelOptions)
|
||
|
d.Set("kernel_options_post", system.KernelOptionsPost)
|
||
|
d.Set("kickstart", system.Kickstart)
|
||
|
d.Set("ks_meta", system.KSMeta)
|
||
|
d.Set("ldap_enabled", system.LDAPEnabled)
|
||
|
d.Set("ldap_type", system.LDAPType)
|
||
|
d.Set("mgmt_classes", system.MGMTClasses)
|
||
|
d.Set("mgmt_parameters", system.MGMTParameters)
|
||
|
d.Set("monit_enabled", system.MonitEnabled)
|
||
|
d.Set("name_servers_search", system.NameServersSearch)
|
||
|
d.Set("name_servers", system.NameServers)
|
||
|
d.Set("netboot_enabled", system.NetbootEnabled)
|
||
|
d.Set("owners", system.Owners)
|
||
|
d.Set("power_address", system.PowerAddress)
|
||
|
d.Set("power_id", system.PowerID)
|
||
|
d.Set("power_pass", system.PowerPass)
|
||
|
d.Set("power_type", system.PowerType)
|
||
|
d.Set("power_user", system.PowerUser)
|
||
|
d.Set("profile", system.Profile)
|
||
|
d.Set("proxy", system.Proxy)
|
||
|
d.Set("redhat_management_key", system.RedHatManagementKey)
|
||
|
d.Set("redhat_management_server", system.RedHatManagementServer)
|
||
|
d.Set("status", system.Status)
|
||
|
d.Set("template_files", system.TemplateFiles)
|
||
|
d.Set("template_remote_kickstarts", system.TemplateRemoteKickstarts)
|
||
|
d.Set("virt_auto_boot", system.VirtAutoBoot)
|
||
|
d.Set("virt_file_size", system.VirtFileSize)
|
||
|
d.Set("virt_cpus", system.VirtCPUs)
|
||
|
d.Set("virt_type", system.VirtType)
|
||
|
d.Set("virt_path", system.VirtPath)
|
||
|
d.Set("virt_pxe_boot", system.VirtPXEBoot)
|
||
|
d.Set("virt_ram", system.VirtRam)
|
||
|
d.Set("virt_disk_driver", system.VirtDiskDriver)
|
||
|
|
||
|
// Get all interfaces that the System has
|
||
|
allInterfaces, err := system.GetInterfaces()
|
||
|
if err != nil {
|
||
|
return fmt.Errorf("Cobbler System %s: Error getting interfaces: %s", system.Name, err)
|
||
|
}
|
||
|
|
||
|
// Build a generic map array with the interface attributes
|
||
|
var systemInterfaces []map[string]interface{}
|
||
|
for interfaceName, interfaceInfo := range allInterfaces {
|
||
|
iface := make(map[string]interface{})
|
||
|
iface["name"] = interfaceName
|
||
|
iface["cnames"] = interfaceInfo.CNAMEs
|
||
|
iface["dhcp_tag"] = interfaceInfo.DHCPTag
|
||
|
iface["dns_name"] = interfaceInfo.DNSName
|
||
|
iface["bonding_opts"] = interfaceInfo.BondingOpts
|
||
|
iface["bridge_opts"] = interfaceInfo.BridgeOpts
|
||
|
iface["gateway"] = interfaceInfo.Gateway
|
||
|
iface["interface_type"] = interfaceInfo.InterfaceType
|
||
|
iface["interface_master"] = interfaceInfo.InterfaceMaster
|
||
|
iface["ip_address"] = interfaceInfo.IPAddress
|
||
|
iface["ipv6_address"] = interfaceInfo.IPv6Address
|
||
|
iface["ipv6_secondaries"] = interfaceInfo.IPv6Secondaries
|
||
|
iface["ipv6_mtu"] = interfaceInfo.IPv6MTU
|
||
|
iface["ipv6_static_routes"] = interfaceInfo.IPv6StaticRoutes
|
||
|
iface["ipv6_default_gateway"] = interfaceInfo.IPv6DefaultGateway
|
||
|
iface["mac_address"] = interfaceInfo.MACAddress
|
||
|
iface["management"] = interfaceInfo.Management
|
||
|
iface["netmask"] = interfaceInfo.Netmask
|
||
|
iface["static"] = interfaceInfo.Static
|
||
|
iface["static_Routes"] = interfaceInfo.StaticRoutes
|
||
|
iface["virt_bridge"] = interfaceInfo.VirtBridge
|
||
|
systemInterfaces = append(systemInterfaces, iface)
|
||
|
}
|
||
|
|
||
|
d.Set("interface", systemInterfaces)
|
||
|
|
||
|
return nil
|
||
|
}
|
||
|
|
||
|
func resourceSystemUpdate(d *schema.ResourceData, meta interface{}) error {
|
||
|
systemSyncLock.Lock()
|
||
|
defer systemSyncLock.Unlock()
|
||
|
|
||
|
config := meta.(*Config)
|
||
|
|
||
|
// Retrieve the existing system entry from Cobbler
|
||
|
system, err := config.cobblerClient.GetSystem(d.Id())
|
||
|
if err != nil {
|
||
|
return fmt.Errorf("Cobbler System: Error Reading (%s): %s", d.Id(), err)
|
||
|
}
|
||
|
|
||
|
// Get a list of the old interfaces
|
||
|
currentInterfaces, err := system.GetInterfaces()
|
||
|
if err != nil {
|
||
|
return fmt.Errorf("Error getting interfaces: %s", err)
|
||
|
}
|
||
|
log.Printf("[DEBUG] Cobbler System Interfaces: %#v", currentInterfaces)
|
||
|
|
||
|
// Create a new cobblerclient.System struct with the new information
|
||
|
newSystem := buildSystem(d)
|
||
|
|
||
|
// Attempt to update the system with new information
|
||
|
log.Printf("[DEBUG] Cobbler System: Updating System (%s) with options: %+v", d.Id(), system)
|
||
|
err = config.cobblerClient.UpdateSystem(&newSystem)
|
||
|
if err != nil {
|
||
|
return fmt.Errorf("Cobbler System: Error Updating (%s): %s", d.Id(), err)
|
||
|
}
|
||
|
|
||
|
if d.HasChange("interface") {
|
||
|
oldInterfaces, newInterfaces := d.GetChange("interface")
|
||
|
oldInterfacesSet := oldInterfaces.(*schema.Set)
|
||
|
newInterfacesSet := newInterfaces.(*schema.Set)
|
||
|
interfacesToRemove := oldInterfacesSet.Difference(newInterfacesSet)
|
||
|
|
||
|
oldIfaces := buildSystemInterfaces(interfacesToRemove)
|
||
|
newIfaces := buildSystemInterfaces(newInterfacesSet)
|
||
|
|
||
|
for interfaceName, interfaceInfo := range oldIfaces {
|
||
|
if _, ok := newIfaces[interfaceName]; !ok {
|
||
|
// Interface does not exist in the new set,
|
||
|
// so it has been removed from terraform.
|
||
|
log.Printf("[DEBUG] Cobbler System: Deleting Interface %#v: %#v", interfaceName, interfaceInfo)
|
||
|
|
||
|
if err := system.DeleteInterface(interfaceName); err != nil {
|
||
|
return fmt.Errorf("Cobbler System: Error deleting Interface %s to %s: %s", interfaceName, system.Name, err)
|
||
|
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Modify interfaces that have changed
|
||
|
for interfaceName, interfaceInfo := range newIfaces {
|
||
|
log.Printf("[DEBUG] Cobbler System: New Interface %#v: %#v", interfaceName, interfaceInfo)
|
||
|
|
||
|
if err := system.CreateInterface(interfaceName, interfaceInfo); err != nil {
|
||
|
return fmt.Errorf("Cobbler System: Error adding Interface %s to %s: %s", interfaceName, system.Name, err)
|
||
|
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
log.Printf("[DEBUG] Cobbler System: syncing system")
|
||
|
if err := config.cobblerClient.Sync(); err != nil {
|
||
|
return fmt.Errorf("Cobbler System: Error syncing system: %s", err)
|
||
|
}
|
||
|
|
||
|
return resourceSystemRead(d, meta)
|
||
|
}
|
||
|
|
||
|
func resourceSystemDelete(d *schema.ResourceData, meta interface{}) error {
|
||
|
config := meta.(*Config)
|
||
|
|
||
|
// Attempt to delete the system
|
||
|
if err := config.cobblerClient.DeleteSystem(d.Id()); err != nil {
|
||
|
return fmt.Errorf("Cobbler System: Error Deleting (%s): %s", d.Id(), err)
|
||
|
}
|
||
|
|
||
|
return nil
|
||
|
}
|
||
|
|
||
|
// buildSystem builds a cobblerclient.System out of the Terraform attributes
|
||
|
func buildSystem(d *schema.ResourceData) cobbler.System {
|
||
|
mgmtClasses := []string{}
|
||
|
for _, i := range d.Get("mgmt_classes").([]interface{}) {
|
||
|
mgmtClasses = append(mgmtClasses, i.(string))
|
||
|
}
|
||
|
|
||
|
nameServersSearch := []string{}
|
||
|
for _, i := range d.Get("name_servers_search").([]interface{}) {
|
||
|
nameServersSearch = append(nameServersSearch, i.(string))
|
||
|
}
|
||
|
|
||
|
nameServers := []string{}
|
||
|
for _, i := range d.Get("name_servers").([]interface{}) {
|
||
|
nameServers = append(nameServers, i.(string))
|
||
|
}
|
||
|
|
||
|
owners := []string{}
|
||
|
for _, i := range d.Get("owners").([]interface{}) {
|
||
|
owners = append(owners, i.(string))
|
||
|
}
|
||
|
|
||
|
system := cobbler.System{
|
||
|
BootFiles: d.Get("boot_files").(string),
|
||
|
Comment: d.Get("comment").(string),
|
||
|
EnableGPXE: d.Get("enable_gpxe").(bool),
|
||
|
FetchableFiles: d.Get("fetchable_files").(string),
|
||
|
Gateway: d.Get("gateway").(string),
|
||
|
Hostname: d.Get("hostname").(string),
|
||
|
Image: d.Get("image").(string),
|
||
|
IPv6DefaultDevice: d.Get("ipv6_default_device").(string),
|
||
|
KernelOptions: d.Get("kernel_options").(string),
|
||
|
KernelOptionsPost: d.Get("kernel_options_post").(string),
|
||
|
Kickstart: d.Get("kickstart").(string),
|
||
|
KSMeta: d.Get("ks_meta").(string),
|
||
|
LDAPEnabled: d.Get("ldap_enabled").(bool),
|
||
|
LDAPType: d.Get("ldap_type").(string),
|
||
|
MGMTClasses: mgmtClasses,
|
||
|
MGMTParameters: d.Get("mgmt_parameters").(string),
|
||
|
MonitEnabled: d.Get("monit_enabled").(bool),
|
||
|
Name: d.Get("name").(string),
|
||
|
NameServersSearch: nameServersSearch,
|
||
|
NameServers: nameServers,
|
||
|
NetbootEnabled: d.Get("netboot_enabled").(bool),
|
||
|
Owners: owners,
|
||
|
PowerAddress: d.Get("power_address").(string),
|
||
|
PowerID: d.Get("power_id").(string),
|
||
|
PowerPass: d.Get("power_pass").(string),
|
||
|
PowerType: d.Get("power_type").(string),
|
||
|
PowerUser: d.Get("power_user").(string),
|
||
|
Profile: d.Get("profile").(string),
|
||
|
Proxy: d.Get("proxy").(string),
|
||
|
RedHatManagementKey: d.Get("redhat_management_key").(string),
|
||
|
RedHatManagementServer: d.Get("redhat_management_server").(string),
|
||
|
Status: d.Get("status").(string),
|
||
|
TemplateFiles: d.Get("template_files").(string),
|
||
|
TemplateRemoteKickstarts: d.Get("template_remote_kickstarts").(int),
|
||
|
VirtAutoBoot: d.Get("virt_auto_boot").(string),
|
||
|
VirtFileSize: d.Get("virt_file_size").(string),
|
||
|
VirtCPUs: d.Get("virt_cpus").(string),
|
||
|
VirtType: d.Get("virt_type").(string),
|
||
|
VirtPath: d.Get("virt_path").(string),
|
||
|
VirtPXEBoot: d.Get("virt_pxe_boot").(int),
|
||
|
VirtRam: d.Get("virt_ram").(string),
|
||
|
VirtDiskDriver: d.Get("virt_disk_driver").(string),
|
||
|
}
|
||
|
|
||
|
return system
|
||
|
}
|
||
|
|
||
|
// buildSystemInterface builds a cobblerclient.Interface out of the Terraform attributes
|
||
|
func buildSystemInterfaces(systemInterfaces *schema.Set) cobbler.Interfaces {
|
||
|
interfaces := make(cobbler.Interfaces)
|
||
|
rawInterfaces := systemInterfaces.List()
|
||
|
for _, rawInterface := range rawInterfaces {
|
||
|
rawInterfaceMap := rawInterface.(map[string]interface{})
|
||
|
|
||
|
cnames := []string{}
|
||
|
for _, i := range rawInterfaceMap["cnames"].([]interface{}) {
|
||
|
cnames = append(cnames, i.(string))
|
||
|
}
|
||
|
|
||
|
ipv6Secondaries := []string{}
|
||
|
for _, i := range rawInterfaceMap["ipv6_secondaries"].([]interface{}) {
|
||
|
ipv6Secondaries = append(ipv6Secondaries, i.(string))
|
||
|
}
|
||
|
|
||
|
ipv6StaticRoutes := []string{}
|
||
|
for _, i := range rawInterfaceMap["ipv6_static_routes"].([]interface{}) {
|
||
|
ipv6StaticRoutes = append(ipv6StaticRoutes, i.(string))
|
||
|
}
|
||
|
|
||
|
staticRoutes := []string{}
|
||
|
for _, i := range rawInterfaceMap["static_routes"].([]interface{}) {
|
||
|
staticRoutes = append(staticRoutes, i.(string))
|
||
|
}
|
||
|
|
||
|
interfaceName := rawInterfaceMap["name"].(string)
|
||
|
interfaces[interfaceName] = cobbler.Interface{
|
||
|
CNAMEs: cnames,
|
||
|
DHCPTag: rawInterfaceMap["dhcp_tag"].(string),
|
||
|
DNSName: rawInterfaceMap["dns_name"].(string),
|
||
|
BondingOpts: rawInterfaceMap["bonding_opts"].(string),
|
||
|
BridgeOpts: rawInterfaceMap["bridge_opts"].(string),
|
||
|
Gateway: rawInterfaceMap["gateway"].(string),
|
||
|
InterfaceType: rawInterfaceMap["interface_type"].(string),
|
||
|
InterfaceMaster: rawInterfaceMap["interface_master"].(string),
|
||
|
IPAddress: rawInterfaceMap["ip_address"].(string),
|
||
|
IPv6Address: rawInterfaceMap["ipv6_address"].(string),
|
||
|
IPv6Secondaries: ipv6Secondaries,
|
||
|
IPv6MTU: rawInterfaceMap["ipv6_mtu"].(string),
|
||
|
IPv6StaticRoutes: ipv6StaticRoutes,
|
||
|
IPv6DefaultGateway: rawInterfaceMap["ipv6_default_gateway"].(string),
|
||
|
MACAddress: rawInterfaceMap["mac_address"].(string),
|
||
|
Management: rawInterfaceMap["management"].(bool),
|
||
|
Netmask: rawInterfaceMap["netmask"].(string),
|
||
|
Static: rawInterfaceMap["static"].(bool),
|
||
|
StaticRoutes: staticRoutes,
|
||
|
VirtBridge: rawInterfaceMap["virt_bridge"].(string),
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return interfaces
|
||
|
}
|
||
|
|
||
|
func resourceSystemInterfaceHash(v interface{}) int {
|
||
|
var buf bytes.Buffer
|
||
|
m := v.(map[string]interface{})
|
||
|
|
||
|
buf.WriteString(fmt.Sprintf("%s", m["name"].(string)))
|
||
|
|
||
|
if v, ok := m["cnames"]; ok {
|
||
|
for _, x := range v.([]interface{}) {
|
||
|
buf.WriteString(fmt.Sprintf("%v-", x.(string)))
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if v, ok := m["dhcp_tag"]; ok {
|
||
|
buf.WriteString(fmt.Sprintf("%v-", v.(string)))
|
||
|
}
|
||
|
|
||
|
if v, ok := m["dns_name"]; ok {
|
||
|
buf.WriteString(fmt.Sprintf("%v-", v.(string)))
|
||
|
}
|
||
|
|
||
|
if v, ok := m["bonding_opts"]; ok {
|
||
|
buf.WriteString(fmt.Sprintf("%v-", v.(string)))
|
||
|
}
|
||
|
|
||
|
if v, ok := m["bridge_opts"]; ok {
|
||
|
buf.WriteString(fmt.Sprintf("%v-", v.(string)))
|
||
|
}
|
||
|
|
||
|
if v, ok := m["gateway"]; ok {
|
||
|
buf.WriteString(fmt.Sprintf("%v-", v.(string)))
|
||
|
}
|
||
|
|
||
|
if v, ok := m["interface_type"]; ok {
|
||
|
buf.WriteString(fmt.Sprintf("%v-", v.(string)))
|
||
|
}
|
||
|
|
||
|
if v, ok := m["interface_master"]; ok {
|
||
|
buf.WriteString(fmt.Sprintf("%v-", v.(string)))
|
||
|
}
|
||
|
|
||
|
if v, ok := m["ip_address"]; ok {
|
||
|
buf.WriteString(fmt.Sprintf("%v-", v.(string)))
|
||
|
}
|
||
|
|
||
|
if v, ok := m["ipv6_address"]; ok {
|
||
|
buf.WriteString(fmt.Sprintf("%v-", v.(string)))
|
||
|
}
|
||
|
|
||
|
if v, ok := m["ipv6_secondaries"]; ok {
|
||
|
for _, x := range v.([]interface{}) {
|
||
|
buf.WriteString(fmt.Sprintf("%v-", x.(string)))
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if v, ok := m["ipv6_mtu"]; ok {
|
||
|
buf.WriteString(fmt.Sprintf("%v-", v.(string)))
|
||
|
}
|
||
|
|
||
|
if v, ok := m["ipv6_static_routes"]; ok {
|
||
|
for _, x := range v.([]interface{}) {
|
||
|
buf.WriteString(fmt.Sprintf("%v-", x.(string)))
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if v, ok := m["ipv6_default_gateway"]; ok {
|
||
|
buf.WriteString(fmt.Sprintf("%v-", v.(string)))
|
||
|
}
|
||
|
|
||
|
if v, ok := m["mac_address"]; ok {
|
||
|
buf.WriteString(fmt.Sprintf("%v-", v.(string)))
|
||
|
}
|
||
|
|
||
|
if v, ok := m["management"]; ok {
|
||
|
buf.WriteString(fmt.Sprintf("%v-", v.(bool)))
|
||
|
}
|
||
|
|
||
|
if v, ok := m["netmask"]; ok {
|
||
|
buf.WriteString(fmt.Sprintf("%v-", v.(string)))
|
||
|
}
|
||
|
|
||
|
if v, ok := m["static"]; ok {
|
||
|
buf.WriteString(fmt.Sprintf("%v-", v.(bool)))
|
||
|
}
|
||
|
|
||
|
if v, ok := m["static_Routes"]; ok {
|
||
|
for _, x := range v.([]interface{}) {
|
||
|
buf.WriteString(fmt.Sprintf("%v-", x.(string)))
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if v, ok := m["virt_bridge"]; ok {
|
||
|
buf.WriteString(fmt.Sprintf("%v-", v.(string)))
|
||
|
}
|
||
|
|
||
|
return hashcode.String(buf.String())
|
||
|
}
|