From 0abff89729fc4f2261f9dbb9acc3560963f50c26 Mon Sep 17 00:00:00 2001 From: Roy Golan Date: Fri, 24 Apr 2020 16:21:12 +0300 Subject: [PATCH 1/3] ovirt: a simpler function to get a connection to oVirt API Signed-off-by: Roy Golan --- pkg/asset/installconfig/ovirt/client.go | 19 +++++++++++++++++-- pkg/asset/installconfig/platformcredscheck.go | 8 ++------ pkg/destroy/ovirt/destroyer.go | 8 +------- 3 files changed, 20 insertions(+), 15 deletions(-) diff --git a/pkg/asset/installconfig/ovirt/client.go b/pkg/asset/installconfig/ovirt/client.go index ccbbad3437a..7d526966d35 100644 --- a/pkg/asset/installconfig/ovirt/client.go +++ b/pkg/asset/installconfig/ovirt/client.go @@ -2,11 +2,12 @@ package ovirt import ( ovirtsdk "github.com/ovirt/go-ovirt" + "github.com/pkg/errors" ) -// GetConnection is a convenience method to get a connection to ovirt api +// getConnection is a convenience method to get a connection to ovirt api // form a Config Object. -func GetConnection(ovirtConfig Config) (*ovirtsdk.Connection, error) { +func getConnection(ovirtConfig Config) (*ovirtsdk.Connection, error) { con, err := ovirtsdk.NewConnectionBuilder(). URL(ovirtConfig.URL). Username(ovirtConfig.Username). @@ -19,3 +20,17 @@ func GetConnection(ovirtConfig Config) (*ovirtsdk.Connection, error) { } return con, nil } + +// NewConnection returns a new client connection to oVirt's API endpoint. +// It is the responsibility of the caller to close the connection. +func NewConnection() (*ovirtsdk.Connection, error) { + ovirtConfig, err := NewConfig() + if err != nil { + return nil, errors.Wrap(err, "getting ovirt configuration") + } + con, err := getConnection(ovirtConfig) + if err != nil { + return nil, errors.Wrap(err, "establishing ovirt connection") + } + return con, nil +} diff --git a/pkg/asset/installconfig/platformcredscheck.go b/pkg/asset/installconfig/platformcredscheck.go index b0da015d032..72439114a7c 100644 --- a/pkg/asset/installconfig/platformcredscheck.go +++ b/pkg/asset/installconfig/platformcredscheck.go @@ -65,13 +65,9 @@ func (a *PlatformCredsCheck) Generate(dependencies asset.Parents) error { return errors.Wrap(err, "creating Azure session") } case ovirt.Name: - ovirtConfig, err := ovirtconfig.NewConfig() + con, err := ovirtconfig.NewConnection() if err != nil { - return errors.Wrap(err, "getting ovirt configuration") - } - con, err := ovirtconfig.GetConnection(ovirtConfig) - if err != nil { - return errors.Wrap(err, "establishing ovirt connection") + return errors.Wrap(err, "creating oVirt connection") } err = con.Test() if err != nil { diff --git a/pkg/destroy/ovirt/destroyer.go b/pkg/destroy/ovirt/destroyer.go index 693e7fd4c7d..cf9c70d9dba 100644 --- a/pkg/destroy/ovirt/destroyer.go +++ b/pkg/destroy/ovirt/destroyer.go @@ -21,13 +21,7 @@ type ClusterUninstaller struct { // Run is the entrypoint to start the uninstall process. func (uninstaller *ClusterUninstaller) Run() error { - config, err := ovirt.NewConfig() - if err != nil { - return err - } - - con, err := ovirt.GetConnection(config) - + con, err := ovirt.NewConnection() if err != nil { return fmt.Errorf("failed to initialize connection to ovirt-engine's %s", err) } From 2a95a3d4aee443d8d01a8e81118e8e735d086550 Mon Sep 17 00:00:00 2001 From: Roy Golan Date: Tue, 5 May 2020 23:21:12 +0300 Subject: [PATCH 2/3] ovirt: Add platform validation Signed-off-by: Roy Golan --- pkg/asset/installconfig/installconfig.go | 4 ++++ pkg/asset/installconfig/ovirt/validators.go | 23 +++++++++++++++++++++ pkg/types/ovirt/validation/platform.go | 10 ++++----- 3 files changed, 32 insertions(+), 5 deletions(-) diff --git a/pkg/asset/installconfig/installconfig.go b/pkg/asset/installconfig/installconfig.go index 75875e2aa14..b12cc0d17e0 100644 --- a/pkg/asset/installconfig/installconfig.go +++ b/pkg/asset/installconfig/installconfig.go @@ -14,6 +14,7 @@ import ( icazure "github.com/openshift/installer/pkg/asset/installconfig/azure" icgcp "github.com/openshift/installer/pkg/asset/installconfig/gcp" icopenstack "github.com/openshift/installer/pkg/asset/installconfig/openstack" + icovirt "github.com/openshift/installer/pkg/asset/installconfig/ovirt" "github.com/openshift/installer/pkg/types" "github.com/openshift/installer/pkg/types/conversion" "github.com/openshift/installer/pkg/types/defaults" @@ -173,5 +174,8 @@ func (a *InstallConfig) platformValidation() error { if a.Config.Platform.AWS != nil { return aws.Validate(context.TODO(), a.AWS, a.Config) } + if a.Config.Platform.Ovirt != nil { + return icovirt.Validate(a.Config) + } return field.ErrorList{}.ToAggregate() } diff --git a/pkg/asset/installconfig/ovirt/validators.go b/pkg/asset/installconfig/ovirt/validators.go index 4bbb3fe29fa..3e20d74c76e 100644 --- a/pkg/asset/installconfig/ovirt/validators.go +++ b/pkg/asset/installconfig/ovirt/validators.go @@ -6,8 +6,31 @@ import ( ovirtsdk "github.com/ovirt/go-ovirt" "github.com/pkg/errors" "gopkg.in/AlecAivazis/survey.v1" + "k8s.io/apimachinery/pkg/util/validation/field" + + "github.com/openshift/installer/pkg/types" + "github.com/openshift/installer/pkg/types/ovirt" + "github.com/openshift/installer/pkg/types/ovirt/validation" ) +// Validate executes platform-specific validation. +func Validate(ic *types.InstallConfig) error { + allErrs := field.ErrorList{} + ovirtPlatformPath := field.NewPath("platform", ovirt.Name) + + if ic.Platform.Ovirt == nil { + return errors.New(field.Required( + ovirtPlatformPath, + "oVirt validation requires a oVirt platform configuration").Error()) + } + + allErrs = append( + allErrs, + validation.ValidatePlatform(ic.Platform.Ovirt, ovirtPlatformPath)...) + + return allErrs.ToAggregate() +} + // authenticated takes an ovirt platform and validates // its connection to the API by establishing // the connection and authenticating successfully. diff --git a/pkg/types/ovirt/validation/platform.go b/pkg/types/ovirt/validation/platform.go index 84fc9be6e34..631d8850cf2 100644 --- a/pkg/types/ovirt/validation/platform.go +++ b/pkg/types/ovirt/validation/platform.go @@ -11,19 +11,19 @@ import ( func ValidatePlatform(p *ovirt.Platform, fldPath *field.Path) field.ErrorList { allErrs := field.ErrorList{} if err := validate.UUID(p.ClusterID); err != nil { - allErrs = append(allErrs, field.Invalid(fldPath.Child("clusterID"), p.ClusterID, err.Error())) + allErrs = append(allErrs, field.Invalid(fldPath.Child("ovirt_cluster_id"), p.ClusterID, err.Error())) } if err := validate.UUID(p.StorageDomainID); err != nil { - allErrs = append(allErrs, field.Invalid(fldPath.Child("storageDomainID"), p.StorageDomainID, err.Error())) + allErrs = append(allErrs, field.Invalid(fldPath.Child("ovirt_storage_domain_id"), p.StorageDomainID, err.Error())) } if err := validate.IP(p.APIVIP); err != nil { - allErrs = append(allErrs, field.Invalid(fldPath.Child("apivip"), p.APIVIP, err.Error())) + allErrs = append(allErrs, field.Invalid(fldPath.Child("api_vip"), p.APIVIP, err.Error())) } if err := validate.IP(p.DNSVIP); err != nil { - allErrs = append(allErrs, field.Invalid(fldPath.Child("dnsvip"), p.DNSVIP, err.Error())) + allErrs = append(allErrs, field.Invalid(fldPath.Child("dns_vip"), p.DNSVIP, err.Error())) } if err := validate.IP(p.IngressVIP); err != nil { - allErrs = append(allErrs, field.Invalid(fldPath.Child("ingressvip"), p.IngressVIP, err.Error())) + allErrs = append(allErrs, field.Invalid(fldPath.Child("ingress_vip"), p.IngressVIP, err.Error())) } if p.DefaultMachinePlatform != nil { allErrs = append(allErrs, ValidateMachinePool(p.DefaultMachinePlatform, fldPath.Child("defaultMachinePlatform"))...) From 615242b644953b559dd2c0d09f01b5127d7eaaa9 Mon Sep 17 00:00:00 2001 From: Roy Golan Date: Fri, 3 Apr 2020 14:02:03 +0300 Subject: [PATCH 3/3] ovirt: add vnic profile The vnic profile that all the VM shares can now be configurable through the platform and is part of the wizard, in case there are multiple for the selected network. ```yaml platform: ovirt: vnicProfileID: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx ``` Signed-off-by: Roy Golan --- data/data/ovirt/main.tf | 1 + data/data/ovirt/template/main.tf | 8 +--- data/data/ovirt/template/variables.tf | 6 ++- data/data/ovirt/variables-ovirt.tf | 5 +++ pkg/asset/cluster/tfvars.go | 20 +++++++++ pkg/asset/installconfig/ovirt/client.go | 34 +++++++++++++++ pkg/asset/installconfig/ovirt/network.go | 43 +++++++++++++++++++ pkg/asset/installconfig/ovirt/ovirt.go | 5 +++ .../ovirt/{validators.go => validaton.go} | 38 +++++++++++++++- .../{validators_test.go => validaton_test.go} | 0 pkg/tfvars/ovirt/ovirt.go | 3 ++ pkg/types/defaults/installconfig.go | 3 ++ pkg/types/ovirt/defaults/platform.go | 8 +++- pkg/types/ovirt/defaults/platform_test.go | 4 +- pkg/types/ovirt/platform.go | 10 ++++- pkg/types/ovirt/validation/platform.go | 5 +++ pkg/types/ovirt/validation/platform_test.go | 20 +++++++++ 17 files changed, 198 insertions(+), 15 deletions(-) rename pkg/asset/installconfig/ovirt/{validators.go => validaton.go} (60%) rename pkg/asset/installconfig/ovirt/{validators_test.go => validaton_test.go} (100%) diff --git a/data/data/ovirt/main.tf b/data/data/ovirt/main.tf index 5080734864b..1e024e0d219 100644 --- a/data/data/ovirt/main.tf +++ b/data/data/ovirt/main.tf @@ -16,6 +16,7 @@ module "template" { ovirt_template_mem = var.ovirt_template_mem disk_size_gib = var.ovirt_template_disk_size_gib ovirt_network_name = var.ovirt_network_name + ovirt_vnic_profile_id = var.ovirt_vnic_profile_id } module "bootstrap" { diff --git a/data/data/ovirt/template/main.tf b/data/data/ovirt/template/main.tf index 702be9e29c8..d6dacf4c7cc 100644 --- a/data/data/ovirt/template/main.tf +++ b/data/data/ovirt/template/main.tf @@ -22,12 +22,6 @@ data "ovirt_clusters" "clusters" { } } -// default vnic profile of ovirt's cluster network -data "ovirt_vnic_profiles" "vnic_profiles" { - name_regex = var.ovirt_network_name - network_id = local.network_id -} - // work around the missing regexall in terraform < 0.12.9 // if length(regexall("^Blank.*$", t.name) locals { @@ -59,7 +53,7 @@ resource "ovirt_vm" "tmp_import_vm" { } nics { name = "nic1" - vnic_profile_id = data.ovirt_vnic_profiles.vnic_profiles.vnic_profiles.0.id + vnic_profile_id = var.ovirt_vnic_profile_id } depends_on = [ovirt_image_transfer.releaseimage] } diff --git a/data/data/ovirt/template/variables.tf b/data/data/ovirt/template/variables.tf index 8200b420ad3..3e3c50e200d 100644 --- a/data/data/ovirt/template/variables.tf +++ b/data/data/ovirt/template/variables.tf @@ -30,10 +30,14 @@ variable "openstack_base_image_local_file_path" { variable "ovirt_network_name" { type = string - default = "ovirtmgmt" description = "The name of ovirt's logical network for the selected ovirt cluster." } +variable "ovirt_vnic_profile_id" { + type = string + description = "The ID of the vnic profile of ovirt's logical network." +} + variable "ovirt_template_mem" { type = string } diff --git a/data/data/ovirt/variables-ovirt.tf b/data/data/ovirt/variables-ovirt.tf index 6f363bef6a4..c0c49144d13 100644 --- a/data/data/ovirt/variables-ovirt.tf +++ b/data/data/ovirt/variables-ovirt.tf @@ -46,6 +46,11 @@ variable "ovirt_network_name" { description = "The name of ovirt's logical network for the selected ovirt cluster." } +variable "ovirt_vnic_profile_id" { + type = string + description = "The ID of the vnic profile of ovirt's logical network." +} + variable "ovirt_master_mem" { type = string default = "8192" diff --git a/pkg/asset/cluster/tfvars.go b/pkg/asset/cluster/tfvars.go index c1c2b1eef01..2a6950b3db5 100644 --- a/pkg/asset/cluster/tfvars.go +++ b/pkg/asset/cluster/tfvars.go @@ -414,6 +414,25 @@ func (t *TerraformVariables) Generate(parents asset.Parents) error { if err != nil { return err } + con, err := ovirtconfig.NewConnection() + if err != nil { + return err + } + defer con.Close() + + if installConfig.Config.Platform.Ovirt.VNICProfileID == "" { + profiles, err := ovirtconfig.FetchVNICProfileByClusterNetwork( + con, + installConfig.Config.Platform.Ovirt.ClusterID, + installConfig.Config.Platform.Ovirt.NetworkName) + if err != nil { + return errors.Wrapf(err, "failed to compute values for oVirt platform") + } + if len(profiles) != 1 { + return errors.Wrapf(err, "failed to compute values for oVirt platform, there are multiple vNic profiles.") + } + installConfig.Config.Platform.Ovirt.VNICProfileID = profiles[0].MustId() + } data, err := ovirttfvars.TFVars( config.URL, @@ -423,6 +442,7 @@ func (t *TerraformVariables) Generate(parents asset.Parents) error { installConfig.Config.Platform.Ovirt.ClusterID, installConfig.Config.Platform.Ovirt.StorageDomainID, installConfig.Config.Platform.Ovirt.NetworkName, + installConfig.Config.Platform.Ovirt.VNICProfileID, string(*rhcosImage), clusterID.InfraID, ) diff --git a/pkg/asset/installconfig/ovirt/client.go b/pkg/asset/installconfig/ovirt/client.go index 7d526966d35..589ed5c4ae0 100644 --- a/pkg/asset/installconfig/ovirt/client.go +++ b/pkg/asset/installconfig/ovirt/client.go @@ -1,6 +1,8 @@ package ovirt import ( + "fmt" + ovirtsdk "github.com/ovirt/go-ovirt" "github.com/pkg/errors" ) @@ -34,3 +36,35 @@ func NewConnection() (*ovirtsdk.Connection, error) { } return con, nil } + +// FetchVNICProfileByClusterNetwork returns a list of profiles for the given cluster and network name. +func FetchVNICProfileByClusterNetwork(con *ovirtsdk.Connection, clusterID string, networkName string) ([]*ovirtsdk.VnicProfile, error) { + clusterResponse, err := con.SystemService().ClustersService().ClusterService(clusterID).Get().Follow("networks").Send() + if err != nil { + return nil, err + } + + cluster, ok := clusterResponse.Cluster() + if !ok { + return nil, fmt.Errorf("failed to find cluster with id %s", clusterID) + } + + networks, ok := cluster.Networks() + if !ok { + return nil, fmt.Errorf("no cluster networks for cluster %s [%s]", cluster.MustName(), clusterID) + } + + for _, n := range networks.Slice() { + if n.MustName() != networkName { + continue + } + + profilesGet, err := con.SystemService().NetworksService().NetworkService(n.MustId()).VnicProfilesService().List().Send() + if err != nil { + return nil, fmt.Errorf("failed to fetch vNic profiles") + } + + return profilesGet.MustProfiles().Slice(), nil + } + return nil, fmt.Errorf("there are no vNic profiles for the given cluster ID %s and network name %s", clusterID, networkName) +} diff --git a/pkg/asset/installconfig/ovirt/network.go b/pkg/asset/installconfig/ovirt/network.go index 6690a3aa757..e57f7e1a7d8 100644 --- a/pkg/asset/installconfig/ovirt/network.go +++ b/pkg/asset/installconfig/ovirt/network.go @@ -50,3 +50,46 @@ func askNetwork(c *ovirtsdk4.Connection, p *ovirt.Platform) error { }) return err } + +func askVNICProfileID(c *ovirtsdk4.Connection, p *ovirt.Platform) error { + var profileID string + var profilesByNames = make(map[string]*ovirtsdk4.VnicProfile) + var profileNames []string + profiles, err := FetchVNICProfileByClusterNetwork(c, p.ClusterID, p.NetworkName) + if err != nil { + return err + } + + for _, profile := range profiles { + profilesByNames[profile.MustName()] = profile + profileNames = append(profileNames, profile.MustName()) + } + + if len(profilesByNames) == 1 { + p.VNICProfileID = profilesByNames[profileNames[0]].MustId() + return nil + } + + // we have multiple vnic profile for the selected network + err = survey.AskOne(&survey.Select{ + Message: "VNIC Profile", + Help: "The oVirt VNIC profile of the VMs.", + Options: profileNames, + }, + &profileID, + func(ans interface{}) error { + choice := ans.(string) + sort.Strings(profileNames) + i := sort.SearchStrings(profileNames, choice) + if i == len(profileNames) || profileNames[i] != choice { + return fmt.Errorf("invalid VNIC profile %s", choice) + } + profile, ok := profilesByNames[choice] + if !ok { + return fmt.Errorf("cannot find a VNIC profile id by the name %s", choice) + } + p.VNICProfileID = profile.MustId() + return nil + }) + return err +} diff --git a/pkg/asset/installconfig/ovirt/ovirt.go b/pkg/asset/installconfig/ovirt/ovirt.go index 705d069df44..567ebb46cca 100644 --- a/pkg/asset/installconfig/ovirt/ovirt.go +++ b/pkg/asset/installconfig/ovirt/ovirt.go @@ -52,6 +52,11 @@ func Platform() (*ovirt.Platform, error) { return &p, err } + err = askVNICProfileID(c, &p) + if err != nil { + return &p, err + } + err = survey.Ask([]*survey.Question{ { Prompt: &survey.Input{ diff --git a/pkg/asset/installconfig/ovirt/validators.go b/pkg/asset/installconfig/ovirt/validaton.go similarity index 60% rename from pkg/asset/installconfig/ovirt/validators.go rename to pkg/asset/installconfig/ovirt/validaton.go index 3e20d74c76e..1dcd192410d 100644 --- a/pkg/asset/installconfig/ovirt/validators.go +++ b/pkg/asset/installconfig/ovirt/validaton.go @@ -13,10 +13,10 @@ import ( "github.com/openshift/installer/pkg/types/ovirt/validation" ) -// Validate executes platform-specific validation. +// Validate executes ovirt specific validation func Validate(ic *types.InstallConfig) error { allErrs := field.ErrorList{} - ovirtPlatformPath := field.NewPath("platform", ovirt.Name) + ovirtPlatformPath := field.NewPath("platform", "ovirt") if ic.Platform.Ovirt == nil { return errors.New(field.Required( @@ -28,6 +28,18 @@ func Validate(ic *types.InstallConfig) error { allErrs, validation.ValidatePlatform(ic.Platform.Ovirt, ovirtPlatformPath)...) + con, err := NewConnection() + if err != nil { + return err + } + defer con.Close() + + if err := validateVNICProfile(*ic.Ovirt, con); err != nil { + allErrs = append( + allErrs, + field.Invalid(ovirtPlatformPath.Child("vnicProfileID"), ic.Ovirt.VNICProfileID, err.Error())) + } + return allErrs.ToAggregate() } @@ -60,3 +72,25 @@ func authenticated(c *Config) survey.Validator { } } + +// validate the provided vnic profile exists and belongs the the cluster network +func validateVNICProfile(platform ovirt.Platform, con *ovirtsdk.Connection) error { + if platform.VNICProfileID != "" { + profiles, err := FetchVNICProfileByClusterNetwork(con, platform.ClusterID, platform.NetworkName) + if err != nil { + return err + } + + for _, p := range profiles { + if platform.VNICProfileID == p.MustId() { + return nil + } + } + + return fmt.Errorf( + "vNic profile ID %s does not belong to cluster network %s", + platform.VNICProfileID, + platform.NetworkName) + } + return nil +} diff --git a/pkg/asset/installconfig/ovirt/validators_test.go b/pkg/asset/installconfig/ovirt/validaton_test.go similarity index 100% rename from pkg/asset/installconfig/ovirt/validators_test.go rename to pkg/asset/installconfig/ovirt/validaton_test.go diff --git a/pkg/tfvars/ovirt/ovirt.go b/pkg/tfvars/ovirt/ovirt.go index 33270b400db..00ff791e7be 100644 --- a/pkg/tfvars/ovirt/ovirt.go +++ b/pkg/tfvars/ovirt/ovirt.go @@ -16,6 +16,7 @@ type config struct { ClusterID string `json:"ovirt_cluster_id"` StorageDomainID string `json:"ovirt_storage_domain_id"` NetworkName string `json:"ovirt_network_name,omitempty"` + VNICProfileID string `json:"ovirt_vnic_profile_id,omitempty"` BaseImageName string `json:"openstack_base_image_name,omitempty"` BaseImageLocalFilePath string `json:"openstack_base_image_local_file_path,omitempty"` } @@ -29,6 +30,7 @@ func TFVars( clusterID string, stoarageDomainID string, networkName string, + vnicProfileID string, baseImage string, infraID string) ([]byte, error) { @@ -40,6 +42,7 @@ func TFVars( ClusterID: clusterID, StorageDomainID: stoarageDomainID, NetworkName: networkName, + VNICProfileID: vnicProfileID, BaseImageName: baseImage, } diff --git a/pkg/types/defaults/installconfig.go b/pkg/types/defaults/installconfig.go index ba9ed26c96a..b728f08d941 100644 --- a/pkg/types/defaults/installconfig.go +++ b/pkg/types/defaults/installconfig.go @@ -10,6 +10,7 @@ import ( libvirtdefaults "github.com/openshift/installer/pkg/types/libvirt/defaults" nonedefaults "github.com/openshift/installer/pkg/types/none/defaults" openstackdefaults "github.com/openshift/installer/pkg/types/openstack/defaults" + ovirtdefaults "github.com/openshift/installer/pkg/types/ovirt/defaults" vspheredefaults "github.com/openshift/installer/pkg/types/vsphere/defaults" ) @@ -81,6 +82,8 @@ func SetInstallConfigDefaults(c *types.InstallConfig) { vspheredefaults.SetPlatformDefaults(c.Platform.VSphere, c) case c.Platform.BareMetal != nil: baremetaldefaults.SetPlatformDefaults(c.Platform.BareMetal, c) + case c.Platform.Ovirt != nil: + ovirtdefaults.SetPlatformDefaults(c.Platform.Ovirt) case c.Platform.None != nil: nonedefaults.SetPlatformDefaults(c.Platform.None) } diff --git a/pkg/types/ovirt/defaults/platform.go b/pkg/types/ovirt/defaults/platform.go index eb89db0a4e9..5921ca44026 100644 --- a/pkg/types/ovirt/defaults/platform.go +++ b/pkg/types/ovirt/defaults/platform.go @@ -4,8 +4,12 @@ import ( "github.com/openshift/installer/pkg/types/ovirt" ) +// DefaultNetworkName is the default network name to use in a cluster +const DefaultNetworkName = "ovirtmgmt" + // SetPlatformDefaults sets the defaults for the platform. func SetPlatformDefaults(p *ovirt.Platform) { - // no platform defaults - return + if p.NetworkName == "" { + p.NetworkName = DefaultNetworkName + } } diff --git a/pkg/types/ovirt/defaults/platform_test.go b/pkg/types/ovirt/defaults/platform_test.go index 5f329734779..a3be7c5cbfc 100644 --- a/pkg/types/ovirt/defaults/platform_test.go +++ b/pkg/types/ovirt/defaults/platform_test.go @@ -9,7 +9,9 @@ import ( ) func defaultPlatform() *ovirt.Platform { - return &ovirt.Platform{} + return &ovirt.Platform{ + NetworkName: DefaultNetworkName, + } } func TestSetPlatformDefaults(t *testing.T) { diff --git a/pkg/types/ovirt/platform.go b/pkg/types/ovirt/platform.go index ed46d8464c4..dcb95f96db7 100644 --- a/pkg/types/ovirt/platform.go +++ b/pkg/types/ovirt/platform.go @@ -7,9 +7,15 @@ type Platform struct { ClusterID string `json:"ovirt_cluster_id"` // The target storage domain under which all VM disk would be created. StorageDomainID string `json:"ovirt_storage_domain_id"` - // The target network of all the network interfaces of the nodes. Omitting defaults to ovirtmgmt - // network which is a default network for evert ovirt cluster. + // The target network of all the network interfaces of the nodes. + // +optional + //Omitting defaults to ovirtmgmt network which is a default network for every ovirt cluster. NetworkName string `json:"ovirt_network_name,omitempty"` + //VNICProfileID defines the VNIC profile ID to use the the VM network interfaces. + // +optional + // Default will set the vnic profile id to the profile of the network. If there are multiple + // profiles for that network the installation exits. + VNICProfileID string `json:"vnicProfileID,omitempty"` // APIVIP is an IP which will be served by bootstrap and then pivoted masters, using keepalived APIVIP string `json:"api_vip"` // DNSVIP is the IP of the internal DNS which will be operated by the cluster diff --git a/pkg/types/ovirt/validation/platform.go b/pkg/types/ovirt/validation/platform.go index 631d8850cf2..b66a99bd3b3 100644 --- a/pkg/types/ovirt/validation/platform.go +++ b/pkg/types/ovirt/validation/platform.go @@ -25,6 +25,11 @@ func ValidatePlatform(p *ovirt.Platform, fldPath *field.Path) field.ErrorList { if err := validate.IP(p.IngressVIP); err != nil { allErrs = append(allErrs, field.Invalid(fldPath.Child("ingress_vip"), p.IngressVIP, err.Error())) } + if p.VNICProfileID != "" { + if err := validate.UUID(p.VNICProfileID); err != nil { + allErrs = append(allErrs, field.Invalid(fldPath.Child("vnicProfileID"), p.IngressVIP, err.Error())) + } + } if p.DefaultMachinePlatform != nil { allErrs = append(allErrs, ValidateMachinePool(p.DefaultMachinePlatform, fldPath.Child("defaultMachinePlatform"))...) } diff --git a/pkg/types/ovirt/validation/platform_test.go b/pkg/types/ovirt/validation/platform_test.go index 68d05961286..3743fdffe26 100644 --- a/pkg/types/ovirt/validation/platform_test.go +++ b/pkg/types/ovirt/validation/platform_test.go @@ -13,6 +13,8 @@ func validPlatform() *ovirt.Platform { return &ovirt.Platform{ ClusterID: "0953a3fb-6682-49a6-8767-43f561045a59", StorageDomainID: "57e42205-02ac-46e1-a6d1-07459d94bc51", + VNICProfileID: "57e42205-02ac-46e1-a6d1-07459d94bc52", + NetworkName: "ocp-blue", APIVIP: "10.0.0.1", DNSVIP: "10.0.0.2", IngressVIP: "10.0.0.3", @@ -76,6 +78,24 @@ func TestValidatePlatform(t *testing.T) { }(), valid: false, }, + { + name: "malformed vnic profile id", + platform: func() *ovirt.Platform { + p := validPlatform() + p.VNICProfileID = "abcd-sdf" + return p + }(), + valid: false, + }, + { + name: "valid empty vnic profile id", + platform: func() *ovirt.Platform { + p := validPlatform() + p.VNICProfileID = "" + return p + }(), + valid: true, + }, { name: "valid machine pool", platform: func() *ovirt.Platform {