github.com/vtorhonen/terraform@v0.9.0-beta2.0.20170307220345-5d894e4ffda7/builtin/providers/cobbler/resource_cobbler_system.go (about)

     1  package cobbler
     2  
     3  import (
     4  	"bytes"
     5  	"fmt"
     6  	"log"
     7  	"sync"
     8  
     9  	"github.com/hashicorp/terraform/helper/hashcode"
    10  	"github.com/hashicorp/terraform/helper/schema"
    11  	cobbler "github.com/jtopjian/cobblerclient"
    12  )
    13  
    14  var systemSyncLock sync.Mutex
    15  
    16  func resourceSystem() *schema.Resource {
    17  	return &schema.Resource{
    18  		Create: resourceSystemCreate,
    19  		Read:   resourceSystemRead,
    20  		Update: resourceSystemUpdate,
    21  		Delete: resourceSystemDelete,
    22  
    23  		Schema: map[string]*schema.Schema{
    24  			"boot_files": &schema.Schema{
    25  				Type:     schema.TypeString,
    26  				Optional: true,
    27  				Computed: true,
    28  			},
    29  
    30  			"comment": &schema.Schema{
    31  				Type:     schema.TypeString,
    32  				Optional: true,
    33  				Computed: true,
    34  			},
    35  
    36  			"enable_gpxe": &schema.Schema{
    37  				Type:     schema.TypeBool,
    38  				Optional: true,
    39  				Computed: true,
    40  			},
    41  
    42  			"fetchable_files": &schema.Schema{
    43  				Type:     schema.TypeString,
    44  				Optional: true,
    45  				Computed: true,
    46  			},
    47  
    48  			"gateway": &schema.Schema{
    49  				Type:     schema.TypeString,
    50  				Optional: true,
    51  				Computed: true,
    52  			},
    53  
    54  			"hostname": &schema.Schema{
    55  				Type:     schema.TypeString,
    56  				Optional: true,
    57  				Computed: true,
    58  			},
    59  
    60  			"image": &schema.Schema{
    61  				Type:     schema.TypeString,
    62  				Optional: true,
    63  				Computed: true,
    64  			},
    65  
    66  			"interface": &schema.Schema{
    67  				Type:     schema.TypeSet,
    68  				Optional: true,
    69  				Computed: true,
    70  				Elem: &schema.Resource{
    71  					Schema: map[string]*schema.Schema{
    72  						"name": &schema.Schema{
    73  							Type:     schema.TypeString,
    74  							Required: true,
    75  						},
    76  
    77  						"cnames": &schema.Schema{
    78  							Type:     schema.TypeList,
    79  							Optional: true,
    80  							Computed: true,
    81  							Elem:     &schema.Schema{Type: schema.TypeString},
    82  						},
    83  
    84  						"dhcp_tag": &schema.Schema{
    85  							Type:     schema.TypeString,
    86  							Optional: true,
    87  							Computed: true,
    88  						},
    89  
    90  						"dns_name": &schema.Schema{
    91  							Type:     schema.TypeString,
    92  							Optional: true,
    93  							Computed: true,
    94  						},
    95  
    96  						"bonding_opts": &schema.Schema{
    97  							Type:     schema.TypeString,
    98  							Optional: true,
    99  							Computed: true,
   100  						},
   101  
   102  						"bridge_opts": &schema.Schema{
   103  							Type:     schema.TypeString,
   104  							Optional: true,
   105  							Computed: true,
   106  						},
   107  
   108  						"gateway": &schema.Schema{
   109  							Type:     schema.TypeString,
   110  							Optional: true,
   111  							Computed: true,
   112  						},
   113  
   114  						"interface_type": &schema.Schema{
   115  							Type:     schema.TypeString,
   116  							Optional: true,
   117  							Computed: true,
   118  						},
   119  
   120  						"interface_master": &schema.Schema{
   121  							Type:     schema.TypeString,
   122  							Optional: true,
   123  							Computed: true,
   124  						},
   125  
   126  						"ip_address": &schema.Schema{
   127  							Type:     schema.TypeString,
   128  							Optional: true,
   129  							Computed: true,
   130  						},
   131  
   132  						"ipv6_address": &schema.Schema{
   133  							Type:     schema.TypeString,
   134  							Optional: true,
   135  							Computed: true,
   136  						},
   137  
   138  						"ipv6_secondaries": &schema.Schema{
   139  							Type:     schema.TypeList,
   140  							Optional: true,
   141  							Computed: true,
   142  							Elem:     &schema.Schema{Type: schema.TypeString},
   143  						},
   144  
   145  						"ipv6_mtu": &schema.Schema{
   146  							Type:     schema.TypeString,
   147  							Optional: true,
   148  							Computed: true,
   149  						},
   150  
   151  						"ipv6_static_routes": &schema.Schema{
   152  							Type:     schema.TypeList,
   153  							Optional: true,
   154  							Computed: true,
   155  							Elem:     &schema.Schema{Type: schema.TypeString},
   156  						},
   157  
   158  						"ipv6_default_gateway": &schema.Schema{
   159  							Type:     schema.TypeString,
   160  							Optional: true,
   161  							Computed: true,
   162  						},
   163  
   164  						"mac_address": &schema.Schema{
   165  							Type:     schema.TypeString,
   166  							Optional: true,
   167  							Computed: true,
   168  						},
   169  
   170  						"management": &schema.Schema{
   171  							Type:     schema.TypeBool,
   172  							Optional: true,
   173  							Computed: true,
   174  						},
   175  
   176  						"netmask": &schema.Schema{
   177  							Type:     schema.TypeString,
   178  							Optional: true,
   179  							Computed: true,
   180  						},
   181  
   182  						"static": &schema.Schema{
   183  							Type:     schema.TypeBool,
   184  							Optional: true,
   185  							Computed: true,
   186  						},
   187  
   188  						"static_routes": &schema.Schema{
   189  							Type:     schema.TypeList,
   190  							Optional: true,
   191  							Computed: true,
   192  							Elem:     &schema.Schema{Type: schema.TypeString},
   193  						},
   194  
   195  						"virt_bridge": &schema.Schema{
   196  							Type:     schema.TypeString,
   197  							Optional: true,
   198  							Computed: true,
   199  						},
   200  					},
   201  				},
   202  				Set: resourceSystemInterfaceHash,
   203  			},
   204  
   205  			"ipv6_default_device": &schema.Schema{
   206  				Type:     schema.TypeString,
   207  				Optional: true,
   208  				Computed: true,
   209  			},
   210  
   211  			"kernel_options": &schema.Schema{
   212  				Type:     schema.TypeString,
   213  				Optional: true,
   214  				Computed: true,
   215  			},
   216  
   217  			"kernel_options_post": &schema.Schema{
   218  				Type:     schema.TypeString,
   219  				Optional: true,
   220  				Computed: true,
   221  			},
   222  
   223  			"kickstart": &schema.Schema{
   224  				Type:     schema.TypeString,
   225  				Optional: true,
   226  				Computed: true,
   227  			},
   228  
   229  			"ks_meta": &schema.Schema{
   230  				Type:     schema.TypeString,
   231  				Optional: true,
   232  				Computed: true,
   233  			},
   234  
   235  			"ldap_enabled": &schema.Schema{
   236  				Type:     schema.TypeBool,
   237  				Optional: true,
   238  				Computed: true,
   239  			},
   240  
   241  			"ldap_type": &schema.Schema{
   242  				Type:     schema.TypeString,
   243  				Optional: true,
   244  				Computed: true,
   245  			},
   246  
   247  			"mgmt_classes": &schema.Schema{
   248  				Type:     schema.TypeList,
   249  				Optional: true,
   250  				Computed: true,
   251  				Elem:     &schema.Schema{Type: schema.TypeString},
   252  			},
   253  
   254  			"mgmt_parameters": &schema.Schema{
   255  				Type:     schema.TypeString,
   256  				Optional: true,
   257  				Computed: true,
   258  			},
   259  
   260  			"monit_enabled": &schema.Schema{
   261  				Type:     schema.TypeBool,
   262  				Optional: true,
   263  				Computed: true,
   264  			},
   265  
   266  			"name": &schema.Schema{
   267  				Type:     schema.TypeString,
   268  				Required: true,
   269  				ForceNew: true,
   270  			},
   271  
   272  			"name_servers_search": &schema.Schema{
   273  				Type:     schema.TypeList,
   274  				Optional: true,
   275  				Computed: true,
   276  				Elem:     &schema.Schema{Type: schema.TypeString},
   277  			},
   278  
   279  			"name_servers": &schema.Schema{
   280  				Type:     schema.TypeList,
   281  				Optional: true,
   282  				Computed: true,
   283  				Elem:     &schema.Schema{Type: schema.TypeString},
   284  			},
   285  
   286  			"netboot_enabled": &schema.Schema{
   287  				Type:     schema.TypeBool,
   288  				Optional: true,
   289  				Computed: true,
   290  			},
   291  
   292  			"owners": &schema.Schema{
   293  				Type:     schema.TypeList,
   294  				Optional: true,
   295  				Computed: true,
   296  				Elem:     &schema.Schema{Type: schema.TypeString},
   297  			},
   298  
   299  			"power_address": &schema.Schema{
   300  				Type:     schema.TypeString,
   301  				Optional: true,
   302  				Computed: true,
   303  			},
   304  
   305  			"power_id": &schema.Schema{
   306  				Type:     schema.TypeString,
   307  				Optional: true,
   308  				Computed: true,
   309  			},
   310  
   311  			"power_pass": &schema.Schema{
   312  				Type:     schema.TypeString,
   313  				Optional: true,
   314  				Computed: true,
   315  			},
   316  
   317  			"power_type": &schema.Schema{
   318  				Type:     schema.TypeString,
   319  				Optional: true,
   320  				Computed: true,
   321  			},
   322  
   323  			"power_user": &schema.Schema{
   324  				Type:     schema.TypeString,
   325  				Optional: true,
   326  				Computed: true,
   327  			},
   328  
   329  			"profile": &schema.Schema{
   330  				Type:     schema.TypeString,
   331  				Required: true,
   332  			},
   333  
   334  			"proxy": &schema.Schema{
   335  				Type:     schema.TypeString,
   336  				Optional: true,
   337  				Computed: true,
   338  			},
   339  
   340  			"redhat_management_key": &schema.Schema{
   341  				Type:     schema.TypeString,
   342  				Optional: true,
   343  				Computed: true,
   344  			},
   345  
   346  			"redhat_management_server": &schema.Schema{
   347  				Type:     schema.TypeString,
   348  				Optional: true,
   349  				Computed: true,
   350  			},
   351  
   352  			"status": &schema.Schema{
   353  				Type:     schema.TypeString,
   354  				Optional: true,
   355  				Computed: true,
   356  			},
   357  
   358  			"template_files": &schema.Schema{
   359  				Type:     schema.TypeString,
   360  				Optional: true,
   361  				Computed: true,
   362  			},
   363  
   364  			"template_remote_kickstarts": &schema.Schema{
   365  				Type:     schema.TypeInt,
   366  				Optional: true,
   367  				Computed: true,
   368  			},
   369  
   370  			"virt_auto_boot": &schema.Schema{
   371  				Type:     schema.TypeString,
   372  				Optional: true,
   373  				Computed: true,
   374  			},
   375  
   376  			"virt_file_size": &schema.Schema{
   377  				Type:     schema.TypeString,
   378  				Optional: true,
   379  				Computed: true,
   380  			},
   381  
   382  			"virt_cpus": &schema.Schema{
   383  				Type:     schema.TypeString,
   384  				Optional: true,
   385  				Computed: true,
   386  			},
   387  
   388  			"virt_type": &schema.Schema{
   389  				Type:     schema.TypeString,
   390  				Optional: true,
   391  				Computed: true,
   392  			},
   393  
   394  			"virt_path": &schema.Schema{
   395  				Type:     schema.TypeString,
   396  				Optional: true,
   397  				Computed: true,
   398  			},
   399  
   400  			"virt_pxe_boot": &schema.Schema{
   401  				Type:     schema.TypeInt,
   402  				Optional: true,
   403  				Computed: true,
   404  			},
   405  
   406  			"virt_ram": &schema.Schema{
   407  				Type:     schema.TypeString,
   408  				Optional: true,
   409  				Computed: true,
   410  			},
   411  
   412  			"virt_disk_driver": &schema.Schema{
   413  				Type:     schema.TypeString,
   414  				Optional: true,
   415  				Computed: true,
   416  			},
   417  		},
   418  	}
   419  }
   420  
   421  func resourceSystemCreate(d *schema.ResourceData, meta interface{}) error {
   422  	systemSyncLock.Lock()
   423  	defer systemSyncLock.Unlock()
   424  
   425  	config := meta.(*Config)
   426  
   427  	// Create a cobblerclient.System struct
   428  	system := buildSystem(d)
   429  
   430  	// Attempt to create the System
   431  	log.Printf("[DEBUG] Cobbler System: Create Options: %#v", system)
   432  	newSystem, err := config.cobblerClient.CreateSystem(system)
   433  	if err != nil {
   434  		return fmt.Errorf("Cobbler System: Error Creating: %s", err)
   435  	}
   436  
   437  	// Build cobblerclient.Interface structs
   438  	interfaces := buildSystemInterfaces(d.Get("interface").(*schema.Set))
   439  
   440  	// Add each interface to the system
   441  	for interfaceName, interfaceInfo := range interfaces {
   442  		log.Printf("[DEBUG] Cobbler System Interface %#v: %#v", interfaceName, interfaceInfo)
   443  		if err := newSystem.CreateInterface(interfaceName, interfaceInfo); err != nil {
   444  			return fmt.Errorf("Cobbler System: Error adding Interface %s to %s: %s", interfaceName, newSystem.Name, err)
   445  		}
   446  	}
   447  
   448  	log.Printf("[DEBUG] Cobbler System: Created System: %#v", newSystem)
   449  	d.SetId(newSystem.Name)
   450  
   451  	log.Printf("[DEBUG] Cobbler System: syncing system")
   452  	if err := config.cobblerClient.Sync(); err != nil {
   453  		return fmt.Errorf("Cobbler System: Error syncing system: %s", err)
   454  	}
   455  
   456  	return resourceSystemRead(d, meta)
   457  }
   458  
   459  func resourceSystemRead(d *schema.ResourceData, meta interface{}) error {
   460  	config := meta.(*Config)
   461  
   462  	// Retrieve the system entry from Cobbler
   463  	system, err := config.cobblerClient.GetSystem(d.Id())
   464  	if err != nil {
   465  		return fmt.Errorf("Cobbler System: Error Reading (%s): %s", d.Id(), err)
   466  	}
   467  
   468  	// Set all fields
   469  	d.Set("boot_files", system.BootFiles)
   470  	d.Set("comment", system.Comment)
   471  	d.Set("enable_gpxe", system.EnableGPXE)
   472  	d.Set("fetchable_files", system.FetchableFiles)
   473  	d.Set("gateway", system.Gateway)
   474  	d.Set("hostname", system.Hostname)
   475  	d.Set("image", system.Image)
   476  	d.Set("ipv6_default_device", system.IPv6DefaultDevice)
   477  	d.Set("kernel_options", system.KernelOptions)
   478  	d.Set("kernel_options_post", system.KernelOptionsPost)
   479  	d.Set("kickstart", system.Kickstart)
   480  	d.Set("ks_meta", system.KSMeta)
   481  	d.Set("ldap_enabled", system.LDAPEnabled)
   482  	d.Set("ldap_type", system.LDAPType)
   483  	d.Set("mgmt_classes", system.MGMTClasses)
   484  	d.Set("mgmt_parameters", system.MGMTParameters)
   485  	d.Set("monit_enabled", system.MonitEnabled)
   486  	d.Set("name_servers_search", system.NameServersSearch)
   487  	d.Set("name_servers", system.NameServers)
   488  	d.Set("netboot_enabled", system.NetbootEnabled)
   489  	d.Set("owners", system.Owners)
   490  	d.Set("power_address", system.PowerAddress)
   491  	d.Set("power_id", system.PowerID)
   492  	d.Set("power_pass", system.PowerPass)
   493  	d.Set("power_type", system.PowerType)
   494  	d.Set("power_user", system.PowerUser)
   495  	d.Set("profile", system.Profile)
   496  	d.Set("proxy", system.Proxy)
   497  	d.Set("redhat_management_key", system.RedHatManagementKey)
   498  	d.Set("redhat_management_server", system.RedHatManagementServer)
   499  	d.Set("status", system.Status)
   500  	d.Set("template_files", system.TemplateFiles)
   501  	d.Set("template_remote_kickstarts", system.TemplateRemoteKickstarts)
   502  	d.Set("virt_auto_boot", system.VirtAutoBoot)
   503  	d.Set("virt_file_size", system.VirtFileSize)
   504  	d.Set("virt_cpus", system.VirtCPUs)
   505  	d.Set("virt_type", system.VirtType)
   506  	d.Set("virt_path", system.VirtPath)
   507  	d.Set("virt_pxe_boot", system.VirtPXEBoot)
   508  	d.Set("virt_ram", system.VirtRam)
   509  	d.Set("virt_disk_driver", system.VirtDiskDriver)
   510  
   511  	// Get all interfaces that the System has
   512  	allInterfaces, err := system.GetInterfaces()
   513  	if err != nil {
   514  		return fmt.Errorf("Cobbler System %s: Error getting interfaces: %s", system.Name, err)
   515  	}
   516  
   517  	// Build a generic map array with the interface attributes
   518  	var systemInterfaces []map[string]interface{}
   519  	for interfaceName, interfaceInfo := range allInterfaces {
   520  		iface := make(map[string]interface{})
   521  		iface["name"] = interfaceName
   522  		iface["cnames"] = interfaceInfo.CNAMEs
   523  		iface["dhcp_tag"] = interfaceInfo.DHCPTag
   524  		iface["dns_name"] = interfaceInfo.DNSName
   525  		iface["bonding_opts"] = interfaceInfo.BondingOpts
   526  		iface["bridge_opts"] = interfaceInfo.BridgeOpts
   527  		iface["gateway"] = interfaceInfo.Gateway
   528  		iface["interface_type"] = interfaceInfo.InterfaceType
   529  		iface["interface_master"] = interfaceInfo.InterfaceMaster
   530  		iface["ip_address"] = interfaceInfo.IPAddress
   531  		iface["ipv6_address"] = interfaceInfo.IPv6Address
   532  		iface["ipv6_secondaries"] = interfaceInfo.IPv6Secondaries
   533  		iface["ipv6_mtu"] = interfaceInfo.IPv6MTU
   534  		iface["ipv6_static_routes"] = interfaceInfo.IPv6StaticRoutes
   535  		iface["ipv6_default_gateway"] = interfaceInfo.IPv6DefaultGateway
   536  		iface["mac_address"] = interfaceInfo.MACAddress
   537  		iface["management"] = interfaceInfo.Management
   538  		iface["netmask"] = interfaceInfo.Netmask
   539  		iface["static"] = interfaceInfo.Static
   540  		iface["static_Routes"] = interfaceInfo.StaticRoutes
   541  		iface["virt_bridge"] = interfaceInfo.VirtBridge
   542  		systemInterfaces = append(systemInterfaces, iface)
   543  	}
   544  
   545  	d.Set("interface", systemInterfaces)
   546  
   547  	return nil
   548  }
   549  
   550  func resourceSystemUpdate(d *schema.ResourceData, meta interface{}) error {
   551  	systemSyncLock.Lock()
   552  	defer systemSyncLock.Unlock()
   553  
   554  	config := meta.(*Config)
   555  
   556  	// Retrieve the existing system entry from Cobbler
   557  	system, err := config.cobblerClient.GetSystem(d.Id())
   558  	if err != nil {
   559  		return fmt.Errorf("Cobbler System: Error Reading (%s): %s", d.Id(), err)
   560  	}
   561  
   562  	// Get a list of the old interfaces
   563  	currentInterfaces, err := system.GetInterfaces()
   564  	if err != nil {
   565  		return fmt.Errorf("Error getting interfaces: %s", err)
   566  	}
   567  	log.Printf("[DEBUG] Cobbler System Interfaces: %#v", currentInterfaces)
   568  
   569  	// Create a new cobblerclient.System struct with the new information
   570  	newSystem := buildSystem(d)
   571  
   572  	// Attempt to update the system with new information
   573  	log.Printf("[DEBUG] Cobbler System: Updating System (%s) with options: %+v", d.Id(), system)
   574  	err = config.cobblerClient.UpdateSystem(&newSystem)
   575  	if err != nil {
   576  		return fmt.Errorf("Cobbler System: Error Updating (%s): %s", d.Id(), err)
   577  	}
   578  
   579  	if d.HasChange("interface") {
   580  		oldInterfaces, newInterfaces := d.GetChange("interface")
   581  		oldInterfacesSet := oldInterfaces.(*schema.Set)
   582  		newInterfacesSet := newInterfaces.(*schema.Set)
   583  		interfacesToRemove := oldInterfacesSet.Difference(newInterfacesSet)
   584  
   585  		oldIfaces := buildSystemInterfaces(interfacesToRemove)
   586  		newIfaces := buildSystemInterfaces(newInterfacesSet)
   587  
   588  		for interfaceName, interfaceInfo := range oldIfaces {
   589  			if _, ok := newIfaces[interfaceName]; !ok {
   590  				// Interface does not exist in the new set,
   591  				// so it has been removed from terraform.
   592  				log.Printf("[DEBUG] Cobbler System: Deleting Interface %#v: %#v", interfaceName, interfaceInfo)
   593  
   594  				if err := system.DeleteInterface(interfaceName); err != nil {
   595  					return fmt.Errorf("Cobbler System: Error deleting Interface %s to %s: %s", interfaceName, system.Name, err)
   596  
   597  				}
   598  			}
   599  		}
   600  
   601  		// Modify interfaces that have changed
   602  		for interfaceName, interfaceInfo := range newIfaces {
   603  			log.Printf("[DEBUG] Cobbler System: New Interface %#v: %#v", interfaceName, interfaceInfo)
   604  
   605  			if err := system.CreateInterface(interfaceName, interfaceInfo); err != nil {
   606  				return fmt.Errorf("Cobbler System: Error adding Interface %s to %s: %s", interfaceName, system.Name, err)
   607  
   608  			}
   609  		}
   610  	}
   611  
   612  	log.Printf("[DEBUG] Cobbler System: syncing system")
   613  	if err := config.cobblerClient.Sync(); err != nil {
   614  		return fmt.Errorf("Cobbler System: Error syncing system: %s", err)
   615  	}
   616  
   617  	return resourceSystemRead(d, meta)
   618  }
   619  
   620  func resourceSystemDelete(d *schema.ResourceData, meta interface{}) error {
   621  	config := meta.(*Config)
   622  
   623  	// Attempt to delete the system
   624  	if err := config.cobblerClient.DeleteSystem(d.Id()); err != nil {
   625  		return fmt.Errorf("Cobbler System: Error Deleting (%s): %s", d.Id(), err)
   626  	}
   627  
   628  	return nil
   629  }
   630  
   631  // buildSystem builds a cobblerclient.System out of the Terraform attributes
   632  func buildSystem(d *schema.ResourceData) cobbler.System {
   633  	mgmtClasses := []string{}
   634  	for _, i := range d.Get("mgmt_classes").([]interface{}) {
   635  		mgmtClasses = append(mgmtClasses, i.(string))
   636  	}
   637  
   638  	nameServersSearch := []string{}
   639  	for _, i := range d.Get("name_servers_search").([]interface{}) {
   640  		nameServersSearch = append(nameServersSearch, i.(string))
   641  	}
   642  
   643  	nameServers := []string{}
   644  	for _, i := range d.Get("name_servers").([]interface{}) {
   645  		nameServers = append(nameServers, i.(string))
   646  	}
   647  
   648  	owners := []string{}
   649  	for _, i := range d.Get("owners").([]interface{}) {
   650  		owners = append(owners, i.(string))
   651  	}
   652  
   653  	system := cobbler.System{
   654  		BootFiles:                d.Get("boot_files").(string),
   655  		Comment:                  d.Get("comment").(string),
   656  		EnableGPXE:               d.Get("enable_gpxe").(bool),
   657  		FetchableFiles:           d.Get("fetchable_files").(string),
   658  		Gateway:                  d.Get("gateway").(string),
   659  		Hostname:                 d.Get("hostname").(string),
   660  		Image:                    d.Get("image").(string),
   661  		IPv6DefaultDevice:        d.Get("ipv6_default_device").(string),
   662  		KernelOptions:            d.Get("kernel_options").(string),
   663  		KernelOptionsPost:        d.Get("kernel_options_post").(string),
   664  		Kickstart:                d.Get("kickstart").(string),
   665  		KSMeta:                   d.Get("ks_meta").(string),
   666  		LDAPEnabled:              d.Get("ldap_enabled").(bool),
   667  		LDAPType:                 d.Get("ldap_type").(string),
   668  		MGMTClasses:              mgmtClasses,
   669  		MGMTParameters:           d.Get("mgmt_parameters").(string),
   670  		MonitEnabled:             d.Get("monit_enabled").(bool),
   671  		Name:                     d.Get("name").(string),
   672  		NameServersSearch:        nameServersSearch,
   673  		NameServers:              nameServers,
   674  		NetbootEnabled:           d.Get("netboot_enabled").(bool),
   675  		Owners:                   owners,
   676  		PowerAddress:             d.Get("power_address").(string),
   677  		PowerID:                  d.Get("power_id").(string),
   678  		PowerPass:                d.Get("power_pass").(string),
   679  		PowerType:                d.Get("power_type").(string),
   680  		PowerUser:                d.Get("power_user").(string),
   681  		Profile:                  d.Get("profile").(string),
   682  		Proxy:                    d.Get("proxy").(string),
   683  		RedHatManagementKey:      d.Get("redhat_management_key").(string),
   684  		RedHatManagementServer:   d.Get("redhat_management_server").(string),
   685  		Status:                   d.Get("status").(string),
   686  		TemplateFiles:            d.Get("template_files").(string),
   687  		TemplateRemoteKickstarts: d.Get("template_remote_kickstarts").(int),
   688  		VirtAutoBoot:             d.Get("virt_auto_boot").(string),
   689  		VirtFileSize:             d.Get("virt_file_size").(string),
   690  		VirtCPUs:                 d.Get("virt_cpus").(string),
   691  		VirtType:                 d.Get("virt_type").(string),
   692  		VirtPath:                 d.Get("virt_path").(string),
   693  		VirtPXEBoot:              d.Get("virt_pxe_boot").(int),
   694  		VirtRam:                  d.Get("virt_ram").(string),
   695  		VirtDiskDriver:           d.Get("virt_disk_driver").(string),
   696  	}
   697  
   698  	return system
   699  }
   700  
   701  // buildSystemInterface builds a cobblerclient.Interface out of the Terraform attributes
   702  func buildSystemInterfaces(systemInterfaces *schema.Set) cobbler.Interfaces {
   703  	interfaces := make(cobbler.Interfaces)
   704  	rawInterfaces := systemInterfaces.List()
   705  	for _, rawInterface := range rawInterfaces {
   706  		rawInterfaceMap := rawInterface.(map[string]interface{})
   707  
   708  		cnames := []string{}
   709  		for _, i := range rawInterfaceMap["cnames"].([]interface{}) {
   710  			cnames = append(cnames, i.(string))
   711  		}
   712  
   713  		ipv6Secondaries := []string{}
   714  		for _, i := range rawInterfaceMap["ipv6_secondaries"].([]interface{}) {
   715  			ipv6Secondaries = append(ipv6Secondaries, i.(string))
   716  		}
   717  
   718  		ipv6StaticRoutes := []string{}
   719  		for _, i := range rawInterfaceMap["ipv6_static_routes"].([]interface{}) {
   720  			ipv6StaticRoutes = append(ipv6StaticRoutes, i.(string))
   721  		}
   722  
   723  		staticRoutes := []string{}
   724  		for _, i := range rawInterfaceMap["static_routes"].([]interface{}) {
   725  			staticRoutes = append(staticRoutes, i.(string))
   726  		}
   727  
   728  		interfaceName := rawInterfaceMap["name"].(string)
   729  		interfaces[interfaceName] = cobbler.Interface{
   730  			CNAMEs:             cnames,
   731  			DHCPTag:            rawInterfaceMap["dhcp_tag"].(string),
   732  			DNSName:            rawInterfaceMap["dns_name"].(string),
   733  			BondingOpts:        rawInterfaceMap["bonding_opts"].(string),
   734  			BridgeOpts:         rawInterfaceMap["bridge_opts"].(string),
   735  			Gateway:            rawInterfaceMap["gateway"].(string),
   736  			InterfaceType:      rawInterfaceMap["interface_type"].(string),
   737  			InterfaceMaster:    rawInterfaceMap["interface_master"].(string),
   738  			IPAddress:          rawInterfaceMap["ip_address"].(string),
   739  			IPv6Address:        rawInterfaceMap["ipv6_address"].(string),
   740  			IPv6Secondaries:    ipv6Secondaries,
   741  			IPv6MTU:            rawInterfaceMap["ipv6_mtu"].(string),
   742  			IPv6StaticRoutes:   ipv6StaticRoutes,
   743  			IPv6DefaultGateway: rawInterfaceMap["ipv6_default_gateway"].(string),
   744  			MACAddress:         rawInterfaceMap["mac_address"].(string),
   745  			Management:         rawInterfaceMap["management"].(bool),
   746  			Netmask:            rawInterfaceMap["netmask"].(string),
   747  			Static:             rawInterfaceMap["static"].(bool),
   748  			StaticRoutes:       staticRoutes,
   749  			VirtBridge:         rawInterfaceMap["virt_bridge"].(string),
   750  		}
   751  	}
   752  
   753  	return interfaces
   754  }
   755  
   756  func resourceSystemInterfaceHash(v interface{}) int {
   757  	var buf bytes.Buffer
   758  	m := v.(map[string]interface{})
   759  
   760  	buf.WriteString(fmt.Sprintf("%s", m["name"].(string)))
   761  
   762  	if v, ok := m["cnames"]; ok {
   763  		for _, x := range v.([]interface{}) {
   764  			buf.WriteString(fmt.Sprintf("%v-", x.(string)))
   765  		}
   766  	}
   767  
   768  	if v, ok := m["dhcp_tag"]; ok {
   769  		buf.WriteString(fmt.Sprintf("%v-", v.(string)))
   770  	}
   771  
   772  	if v, ok := m["dns_name"]; ok {
   773  		buf.WriteString(fmt.Sprintf("%v-", v.(string)))
   774  	}
   775  
   776  	if v, ok := m["bonding_opts"]; ok {
   777  		buf.WriteString(fmt.Sprintf("%v-", v.(string)))
   778  	}
   779  
   780  	if v, ok := m["bridge_opts"]; ok {
   781  		buf.WriteString(fmt.Sprintf("%v-", v.(string)))
   782  	}
   783  
   784  	if v, ok := m["gateway"]; ok {
   785  		buf.WriteString(fmt.Sprintf("%v-", v.(string)))
   786  	}
   787  
   788  	if v, ok := m["interface_type"]; ok {
   789  		buf.WriteString(fmt.Sprintf("%v-", v.(string)))
   790  	}
   791  
   792  	if v, ok := m["interface_master"]; ok {
   793  		buf.WriteString(fmt.Sprintf("%v-", v.(string)))
   794  	}
   795  
   796  	if v, ok := m["ip_address"]; ok {
   797  		buf.WriteString(fmt.Sprintf("%v-", v.(string)))
   798  	}
   799  
   800  	if v, ok := m["ipv6_address"]; ok {
   801  		buf.WriteString(fmt.Sprintf("%v-", v.(string)))
   802  	}
   803  
   804  	if v, ok := m["ipv6_secondaries"]; ok {
   805  		for _, x := range v.([]interface{}) {
   806  			buf.WriteString(fmt.Sprintf("%v-", x.(string)))
   807  		}
   808  	}
   809  
   810  	if v, ok := m["ipv6_mtu"]; ok {
   811  		buf.WriteString(fmt.Sprintf("%v-", v.(string)))
   812  	}
   813  
   814  	if v, ok := m["ipv6_static_routes"]; ok {
   815  		for _, x := range v.([]interface{}) {
   816  			buf.WriteString(fmt.Sprintf("%v-", x.(string)))
   817  		}
   818  	}
   819  
   820  	if v, ok := m["ipv6_default_gateway"]; ok {
   821  		buf.WriteString(fmt.Sprintf("%v-", v.(string)))
   822  	}
   823  
   824  	if v, ok := m["mac_address"]; ok {
   825  		buf.WriteString(fmt.Sprintf("%v-", v.(string)))
   826  	}
   827  
   828  	if v, ok := m["management"]; ok {
   829  		buf.WriteString(fmt.Sprintf("%v-", v.(bool)))
   830  	}
   831  
   832  	if v, ok := m["netmask"]; ok {
   833  		buf.WriteString(fmt.Sprintf("%v-", v.(string)))
   834  	}
   835  
   836  	if v, ok := m["static"]; ok {
   837  		buf.WriteString(fmt.Sprintf("%v-", v.(bool)))
   838  	}
   839  
   840  	if v, ok := m["static_Routes"]; ok {
   841  		for _, x := range v.([]interface{}) {
   842  			buf.WriteString(fmt.Sprintf("%v-", x.(string)))
   843  		}
   844  	}
   845  
   846  	if v, ok := m["virt_bridge"]; ok {
   847  		buf.WriteString(fmt.Sprintf("%v-", v.(string)))
   848  	}
   849  
   850  	return hashcode.String(buf.String())
   851  }