func (p *ParamValidatorAndPopulator) ValidateAndPopulate(params *ovfdomain.OVFImportParams) (err error) {
	params.BuildID = p.generateBuildIDIfMissing(params.BuildID)
	if params.Project, err = p.lookupProjectIfMissing(*params.Project); err != nil {
		return err
	}
	if params.Zone, err = p.lookupZoneIfMissing(*params.Project, params.Zone); err != nil {
		return err
	}
	if params.Region, err = p.getRegionFromZone(params.Zone); err != nil {
		return err
	}
	if params.Network, params.Subnet, err = p.NetworkResolver.Resolve(
		params.Network, params.Subnet, params.Region, *params.Project); err != nil {
		return err
	}
	if params.ReleaseTrack, err = p.resolveReleaseTrack(params.ReleaseTrack); err != nil {
		return err
	}
	if params.Deadline, err = p.calculateDeadlineFromTimeout(params.Timeout); err != nil {
		return err
	}
	if params.ScratchBucketGcsPath, err = p.createScratchBucketIfMissing(
		params.ScratchBucketGcsPath, *params.Project, params.Region, params.BuildID); err != nil {
		return err
	}
	params.InstanceNames = strings.ToLower(strings.TrimSpace(params.InstanceNames))
	params.MachineImageName = strings.ToLower(strings.TrimSpace(params.MachineImageName))
	params.Description = strings.TrimSpace(params.Description)
	params.PrivateNetworkIP = strings.TrimSpace(params.PrivateNetworkIP)
	params.NetworkTier = strings.TrimSpace(params.NetworkTier)
	params.ComputeServiceAccount = strings.TrimSpace(params.ComputeServiceAccount)
	params.InstanceServiceAccount = strings.TrimSpace(params.InstanceServiceAccount)
	params.InstanceAccessScopesFlag = strings.TrimSpace(params.InstanceAccessScopesFlag)
	if params.InstanceAccessScopesFlag != "" {
		params.InstanceAccessScopes = strings.Split(params.InstanceAccessScopesFlag, ",")
		for _, scope := range params.InstanceAccessScopes {
			if !strings.HasPrefix(scope, instanceAccessScopePrefix) {
				return daisy.Errf("Scope `%v` is invalid because it doesn't start with `%v`", scope, instanceAccessScopePrefix)
			}
		}
	} else {
		params.InstanceAccessScopes = []string{}
	}
	if params.InstanceNames == "" && params.MachineImageName == "" {
		return daisy.Errf("Either the flag -%v or -%v must be provided", InstanceNameFlagKey, MachineImageNameFlagKey)
	}
	if params.InstanceNames != "" && params.MachineImageName != "" {
		return daisy.Errf("-%v and -%v can't be provided at the same time", InstanceNameFlagKey, MachineImageNameFlagKey)
	}
	if params.IsInstanceImport() {
		instanceNameSplits := strings.Split(params.InstanceNames, ",")
		if len(instanceNameSplits) > 1 {
			return daisy.Errf("OVF import doesn't support multi instance import at this time")
		}
		if params.MachineImageStorageLocation != "" {
			return daisy.Errf("-%v can't be provided when importing an instance", MachineImageStorageLocationFlagKey)
		}
	}
	if err := validation.ValidateStringFlagNotEmpty(params.OvfOvaGcsPath, OvfGcsPathFlagKey); err != nil {
		return err
	}
	if _, err := storageutils.GetBucketNameFromGCSPath(params.OvfOvaGcsPath); err != nil {
		return daisy.Errf("%v should be a path to OVF or OVA package in Cloud Storage", OvfGcsPathFlagKey)
	}
	if params.Labels != "" {
		var err error
		params.UserLabels, err = param.ParseKeyValues(params.Labels)
		if err != nil {
			return err
		}
	}
	if params.Tags != "" {
		params.UserTags = strings.Split(params.Tags, ",")
		for _, tag := range params.UserTags {
			if tag == "" {
				return errors.New("tags cannot be empty")
			}
			if err := validation.ValidateRfc1035Label(tag); err != nil {
				return fmt.Errorf("tag `%v` is not RFC1035 compliant", tag)
			}
		}
	}
	if params.NodeAffinityLabelsFlag != nil {
		var err error
		params.NodeAffinities, params.NodeAffinitiesBeta, err = compute.ParseNodeAffinityLabels(params.NodeAffinityLabelsFlag)
		if err != nil {
			return err
		}
	}
	if params.Hostname != "" {
		err := validation.ValidateFqdn(params.Hostname, HostnameFlagKey)
		if err != nil {
			return err
		}
	}
	return nil
}
ValidateAndPopulate validates OVFImportParams, and populates values that are missing.
It returns an error if params are invalid.
package ovfimporter
import (
	"context"
	"errors"
	"fmt"
	"os"
	"strings"
	"time"
	"cloud.google.com/go/storage"
	"google.golang.org/api/iterator"
	"github.com/GoogleCloudPlatform/compute-image-tools/cli_tools/common/domain"
	"github.com/GoogleCloudPlatform/compute-image-tools/cli_tools/common/utils/compute"
	"github.com/GoogleCloudPlatform/compute-image-tools/cli_tools/common/utils/logging"
	"github.com/GoogleCloudPlatform/compute-image-tools/cli_tools/common/utils/param"
	pathutils "github.com/GoogleCloudPlatform/compute-image-tools/cli_tools/common/utils/path"
	storageutils "github.com/GoogleCloudPlatform/compute-image-tools/cli_tools/common/utils/storage"
	"github.com/GoogleCloudPlatform/compute-image-tools/cli_tools/common/utils/validation"
	ovfdomain "github.com/GoogleCloudPlatform/compute-image-tools/cli_tools/gce_ovf_import/domain"
	"github.com/GoogleCloudPlatform/compute-image-tools/daisy"
)
const (
	InstanceNameFlagKey = "instance-names"
	MachineImageNameFlagKey = "machine-image-name"
	MachineImageStorageLocationFlagKey = "machine-image-storage-location"
	ClientIDFlagKey = "client-id"
	OvfGcsPathFlagKey = "ovf-gcs-path"
	HostnameFlagKey = "hostname"
	instanceAccessScopePrefix = "https://www.googleapis.com/auth/"
)
type ParamValidatorAndPopulator struct {
	metadataClient        domain.MetadataGCEInterface
	zoneValidator         domain.ZoneValidatorInterface
	bucketIteratorCreator domain.BucketIteratorCreatorInterface
	storageClient         domain.StorageClientInterface
	NetworkResolver       param.NetworkResolver
	logger                logging.Logger
}