github.com/openshift/installer@v1.4.17/pkg/tfvars/libvirt/libvirt.go (about)

     1  // Package libvirt contains libvirt-specific Terraform-variable logic.
     2  package libvirt
     3  
     4  import (
     5  	"encoding/json"
     6  	"fmt"
     7  	"net"
     8  	"net/url"
     9  	"os"
    10  	"path/filepath"
    11  	"strconv"
    12  
    13  	"github.com/apparentlymart/go-cidr/cidr"
    14  	"github.com/pkg/errors"
    15  
    16  	"github.com/openshift/cluster-api-provider-libvirt/pkg/apis/libvirtproviderconfig/v1beta1"
    17  	"github.com/openshift/installer/pkg/rhcos/cache"
    18  	"github.com/openshift/installer/pkg/types"
    19  )
    20  
    21  type config struct {
    22  	URI             string              `json:"libvirt_uri,omitempty"`
    23  	Image           string              `json:"os_image,omitempty"`
    24  	IfName          string              `json:"libvirt_network_if"`
    25  	MasterIPs       []string            `json:"libvirt_master_ips,omitempty"`
    26  	BootstrapIP     string              `json:"libvirt_bootstrap_ip,omitempty"`
    27  	MasterMemory    string              `json:"libvirt_master_memory,omitempty"`
    28  	MasterVcpu      string              `json:"libvirt_master_vcpu,omitempty"`
    29  	BootstrapMemory int                 `json:"libvirt_bootstrap_memory,omitempty"`
    30  	MasterDiskSize  string              `json:"libvirt_master_size,omitempty"`
    31  	DnsmasqOptions  []map[string]string `json:"libvirt_dnsmasq_options,omitempty"`
    32  }
    33  
    34  // TFVarsSources contains the parameters to be converted into Terraform variables
    35  type TFVarsSources struct {
    36  	MasterConfig   *v1beta1.LibvirtMachineProviderConfig
    37  	OsImage        string
    38  	MachineCIDR    *net.IPNet
    39  	Bridge         string
    40  	MasterCount    int
    41  	Architecture   types.Architecture
    42  	DnsmasqOptions []map[string]string
    43  }
    44  
    45  // TFVars generates libvirt-specific Terraform variables.
    46  func TFVars(sources TFVarsSources) ([]byte, error) {
    47  	bootstrapIP, err := cidr.Host(sources.MachineCIDR, 10)
    48  	if err != nil {
    49  		return nil, errors.Errorf("failed to generate bootstrap IP: %v", err)
    50  	}
    51  
    52  	masterIPs, err := generateIPs("master", sources.MachineCIDR, sources.MasterCount, 11)
    53  	if err != nil {
    54  		return nil, err
    55  	}
    56  
    57  	osImage := sources.OsImage
    58  	url, err := url.Parse(osImage)
    59  	if err != nil {
    60  		return nil, errors.Wrap(err, "failed to parse image url")
    61  	}
    62  
    63  	if url.Scheme == "file" {
    64  		osImage = filepath.FromSlash(url.Path)
    65  		if _, err = os.Stat(osImage); err != nil {
    66  			return nil, errors.Wrap(err, "failed to access file or directory")
    67  		}
    68  	} else {
    69  		osImage, err = cache.DownloadImageFile(osImage, cache.InstallerApplicationName)
    70  		if err != nil {
    71  			return nil, errors.Wrap(err, "failed to use cached libvirt image")
    72  		}
    73  	}
    74  
    75  	cfg := &config{
    76  		URI:            sources.MasterConfig.URI,
    77  		Image:          osImage,
    78  		IfName:         sources.Bridge,
    79  		BootstrapIP:    bootstrapIP.String(),
    80  		MasterIPs:      masterIPs,
    81  		MasterMemory:   strconv.Itoa(sources.MasterConfig.DomainMemory),
    82  		MasterVcpu:     strconv.Itoa(sources.MasterConfig.DomainVcpu),
    83  		DnsmasqOptions: sources.DnsmasqOptions,
    84  	}
    85  
    86  	if sources.MasterConfig.Volume.VolumeSize != nil {
    87  		// As per https://github.com/hashicorp/terraform/issues/3287 the
    88  		// master disk size needs to be specified as the number of bytes.
    89  		diskSizeInBytes, converted := sources.MasterConfig.Volume.VolumeSize.AsInt64()
    90  		if !converted {
    91  			msgTemplate := "failed to convert master disk size to bytes: %s"
    92  			return nil, fmt.Errorf(msgTemplate, sources.MasterConfig.Volume.VolumeSize)
    93  		}
    94  		cfg.MasterDiskSize = fmt.Sprintf("%d", diskSizeInBytes)
    95  	}
    96  
    97  	return json.MarshalIndent(cfg, "", "  ")
    98  }
    99  
   100  func generateIPs(name string, network *net.IPNet, count int, offset int) ([]string, error) {
   101  	var ips []string
   102  	for i := 0; i < count; i++ {
   103  		ip, err := cidr.Host(network, offset+i)
   104  		if err != nil {
   105  			return nil, fmt.Errorf("failed to generate %s IPs: %v", name, err)
   106  		}
   107  		ips = append(ips, ip.String())
   108  	}
   109  
   110  	return ips, nil
   111  }