github.com/openshift/installer@v1.4.17/pkg/asset/installconfig/ovirt/network.go (about)

     1  package ovirt
     2  
     3  import (
     4  	"fmt"
     5  	"sort"
     6  
     7  	"github.com/AlecAivazis/survey/v2"
     8  	"github.com/AlecAivazis/survey/v2/core"
     9  	ovirtsdk4 "github.com/ovirt/go-ovirt"
    10  	"github.com/pkg/errors"
    11  
    12  	"github.com/openshift/installer/pkg/types"
    13  	"github.com/openshift/installer/pkg/types/defaults"
    14  	"github.com/openshift/installer/pkg/types/ovirt"
    15  	"github.com/openshift/installer/pkg/types/validation"
    16  	"github.com/openshift/installer/pkg/validate"
    17  )
    18  
    19  func askNetwork(c *ovirtsdk4.Connection, p *ovirt.Platform) error {
    20  	var networkName string
    21  	var networkByNames = make(map[string]*ovirtsdk4.Network)
    22  	var networkNames []string
    23  	systemService := c.SystemService()
    24  	networksResponse, err := systemService.ClustersService().ClusterService(p.ClusterID).NetworksService().List().Send()
    25  	if err != nil {
    26  		return err
    27  	}
    28  	networks, ok := networksResponse.Networks()
    29  	if !ok {
    30  		return fmt.Errorf("there are no available networks for cluster %s", p.ClusterID)
    31  	}
    32  
    33  	for _, network := range networks.Slice() {
    34  		networkByNames[network.MustName()] = network
    35  		networkNames = append(networkNames, network.MustName())
    36  	}
    37  	if err := survey.AskOne(
    38  		&survey.Select{
    39  			Message: "Network",
    40  			Help:    "The Engine network of the deployed VMs. 'ovirtmgmt' is the default network. It is recommended to use a dedicated network for each OpenShift cluster.",
    41  			Options: networkNames,
    42  		},
    43  		&networkName,
    44  		survey.WithValidator(func(ans interface{}) error {
    45  			choice := ans.(core.OptionAnswer).Value
    46  			sort.Strings(networkNames)
    47  			i := sort.SearchStrings(networkNames, choice)
    48  			if i == len(networkNames) || networkNames[i] != choice {
    49  				return fmt.Errorf("invalid network %s", choice)
    50  			}
    51  			network, ok := networkByNames[choice]
    52  			if !ok {
    53  				return fmt.Errorf("cannot find a network by name %s", choice)
    54  			}
    55  			p.NetworkName = network.MustName()
    56  			return nil
    57  		}),
    58  	); err != nil {
    59  		return errors.Wrap(err, "failed UserInput")
    60  	}
    61  	return nil
    62  }
    63  
    64  func askVNICProfileID(c *ovirtsdk4.Connection, p *ovirt.Platform) error {
    65  	var profileID string
    66  	var profilesByNames = make(map[string]*ovirtsdk4.VnicProfile)
    67  	var profileNames []string
    68  	profiles, err := FetchVNICProfileByClusterNetwork(c, p.ClusterID, p.NetworkName)
    69  	if err != nil {
    70  		return err
    71  	}
    72  
    73  	for _, profile := range profiles {
    74  		profilesByNames[profile.MustName()] = profile
    75  		profileNames = append(profileNames, profile.MustName())
    76  	}
    77  
    78  	if len(profilesByNames) == 1 {
    79  		p.VNICProfileID = profilesByNames[profileNames[0]].MustId()
    80  		return nil
    81  	}
    82  
    83  	// we have multiple vnic profile for the selected network
    84  	if err := survey.AskOne(
    85  		&survey.Select{
    86  			Message: "VNIC Profile",
    87  			Help:    "The Engine VNIC profile of the VMs.",
    88  			Options: profileNames,
    89  		},
    90  		&profileID,
    91  		survey.WithValidator(func(ans interface{}) error {
    92  			choice := ans.(core.OptionAnswer).Value
    93  			sort.Strings(profileNames)
    94  			i := sort.SearchStrings(profileNames, choice)
    95  			if i == len(profileNames) || profileNames[i] != choice {
    96  				return fmt.Errorf("invalid VNIC profile %s", choice)
    97  			}
    98  			profile, ok := profilesByNames[choice]
    99  			if !ok {
   100  				return fmt.Errorf("cannot find a VNIC profile id by the name %s", choice)
   101  			}
   102  			p.VNICProfileID = profile.MustId()
   103  			return nil
   104  		}),
   105  	); err != nil {
   106  		return errors.Wrap(err, "failed UserInput")
   107  	}
   108  	return nil
   109  }
   110  
   111  func askVIPs(p *ovirt.Platform) error {
   112  	//TODO: Add support to specify multiple VIPs (-> dual-stack)
   113  	var apiVIP, ingressVIP string
   114  
   115  	defaultMachineNetwork := &types.Networking{
   116  		MachineNetwork: []types.MachineNetworkEntry{
   117  			{
   118  				CIDR: *defaults.DefaultMachineCIDR,
   119  			},
   120  		},
   121  	}
   122  
   123  	err := survey.Ask([]*survey.Question{
   124  		{
   125  			Prompt: &survey.Input{
   126  				Message: "Internal API virtual IP",
   127  				Help:    "This is the virtual IP address that will be used to address the OpenShift control plane. Make sure the IP address is not in use.",
   128  				Default: "",
   129  			},
   130  			Validate: survey.ComposeValidators(survey.Required, func(ans interface{}) error {
   131  				err := validate.IP((ans).(string))
   132  				if err != nil {
   133  					return err
   134  				}
   135  				return validation.ValidateIPinMachineCIDR((ans).(string), defaultMachineNetwork)
   136  			}),
   137  		},
   138  	}, &apiVIP)
   139  	if err != nil {
   140  		return errors.Wrap(err, "failed UserInput")
   141  	}
   142  	p.APIVIPs = []string{apiVIP}
   143  
   144  	err = survey.Ask([]*survey.Question{
   145  		{
   146  			Prompt: &survey.Input{
   147  				Message: "Ingress virtual IP",
   148  				Help:    "This is the virtual IP address that will be used to address the OpenShift ingress routers. Make sure the IP address is not in use.",
   149  				Default: "",
   150  			},
   151  			Validate: survey.ComposeValidators(survey.Required, func(ans interface{}) error {
   152  				if apiVIP == (ans.(string)) {
   153  					return fmt.Errorf("%q should not be equal to the Virtual IP address for the API", ans.(string))
   154  				}
   155  				err := validate.IP((ans).(string))
   156  				if err != nil {
   157  					return err
   158  				}
   159  				return validation.ValidateIPinMachineCIDR((ans).(string), defaultMachineNetwork)
   160  			}),
   161  		},
   162  	}, &ingressVIP)
   163  	if err != nil {
   164  		return errors.Wrap(err, "failed UserInput")
   165  	}
   166  	p.IngressVIPs = []string{ingressVIP}
   167  
   168  	return nil
   169  }