func (r *LocatorRef) SetEnv(value string) error {
	var loc loc.Locator
	err := loc.UnmarshalText([]byte(value))
	if err != nil {
		return err
	}
	r.Locator = &loc
	return nil
}
SetEnv implements configure.EnvSetter
package framework
import (
	"bytes"
	"encoding/json"
	"flag"
	"fmt"
	"io/ioutil"
	"os"
	"time"
	"github.com/gravitational/robotest/e2e/framework/defaults"
	"github.com/gravitational/robotest/infra"
	"github.com/gravitational/robotest/infra/providers/aws"
	"github.com/gravitational/robotest/infra/providers/azure"
	"github.com/gravitational/robotest/infra/providers/gce"
	"github.com/gravitational/robotest/infra/terraform"
	"github.com/gravitational/robotest/infra/vagrant"
	"github.com/gravitational/robotest/lib/debug"
	"github.com/gravitational/robotest/lib/loc"
	"github.com/gravitational/configure"
	"github.com/gravitational/trace"
	"github.com/kr/pretty"
	"github.com/onsi/ginkgo"
	"github.com/onsi/ginkgo/config"
	log "github.com/sirupsen/logrus"
	"gopkg.in/yaml.v2"
)
func ConfigureFlags() {
	registerCommonFlags()
	flag.Parse()
	initLogger(debugFlag)
	if debugFlag {
		debug.StartProfiling(fmt.Sprintf("localhost:%v", debugPort))
	}
	err := initTestContext(configFile)
	if err != nil {
		Failf("failed to read configuration from %q: %v", configFile, trace.DebugReport(err))
	}
	err = initTestState(stateConfigFile)
	if err != nil {
		Failf("failed to read state configuration from %q: %v", stateConfigFile, trace.DebugReport(err))
	}
	if testState != nil {
		TestContext.Provisioner = testState.Provisioner
		TestContext.StateDir = testState.StateDir
		if testState.EntryURL != "" {
			TestContext.OpsCenterURL = testState.EntryURL
		}
		if testState.Login != nil {
			TestContext.Login = *testState.Login
		}
		if testState.ServiceLogin != nil {
			TestContext.ServiceLogin = *testState.ServiceLogin
		}
		if testState.ProvisionerState != nil {
			TestContext.Wizard = testState.ProvisionerState.InstallerAddr != ""
		}
		if testState.Application != nil {
			TestContext.Application.Locator = testState.Application
		}
		if testState.Bandwagon != nil {
			TestContext.Bandwagon = *testState.Bandwagon
		}
	}
	if mode == wizardMode || TestContext.Wizard {
		TestContext.Wizard = true
	}
	if mode == provisionMode {
		config.GinkgoConfig.SkipString = ".*"
	}
	if provisionerName != "" {
		TestContext.Provisioner = &Provisioner{
			Type: provisionerType(provisionerName),
		}
	}
	if teardownFlag {
		TestContext.Teardown = teardownFlag
	}
	if dumpFlag {
		TestContext.DumpCore = dumpFlag
	}
	if stateDir != "" {
		TestContext.StateDir = stateDir
	}
	if TestContext.Teardown || TestContext.DumpCore {
		config.GinkgoConfig.SkipString = ".*"
	}
	outputSensitiveConfig(*TestContext)
	if testState != nil {
		outputSensitiveState(*testState)
		if testState.ProvisionerState != nil {
			log.Debugf("[PROVISIONER STATE]: %#v", testState)
		}
	}
}
func (r *TestContextType) Validate() error {
	var errors []error
	if mode == wizardMode && TestContext.Onprem.InstallerURL == "" {
		errors = append(errors, trace.BadParameter("installer URL is required in wizard mode"))
	}
	var command = teardownFlag || dumpFlag || mode == wizardMode
	if !command && TestContext.Login.IsEmpty() {
		log.Warningf("Ops Center login not configured - Ops Center access will likely not be available")
	}
	if TestContext.ServiceLogin.IsEmpty() {
		log.Warningf("service login not configured - reports will likely not be collected")
	}
	if TestContext.Provisioner != nil && TestContext.Onprem.IsEmpty() {
		errors = append(errors, trace.BadParameter("Onprem configuration is required for provisioner %v",
			TestContext.Provisioner.Type))
	}
	return trace.NewAggregate(errors...)
}
func Failf(format string, args ...interface{}) {
	msg := fmt.Sprintf(format, args...)
	log.Error(msg)
	ginkgo.Fail(nowStamp()+": "+msg, 1)
}
var TestContext = &TestContextType{
	Bandwagon: BandwagonConfig{
		Organization: defaults.BandwagonOrganization,
		Username:     defaults.BandwagonUsername,
		Email:        defaults.BandwagonEmail,
		Password:     defaults.BandwagonPassword,
	},
}
var testState *TestState
type TestContextType struct {
	Wizard bool `json:"-" yaml:"-"`
	Provisioner *Provisioner `json:"provisioner" yaml:"provisioner"`
	CloudProvider string `json:"cloud_provider" yaml:"cloud_provider" validate:"omitempty,eq=aws|eq=azure"`
	DumpCore bool `json:"-" yaml:"-"`
	StateDir string `json:"state_dir" yaml:"state_dir" `
	Teardown bool `json:"-" yaml:"-"`
	ForceRemoteAccess bool `json:"remote_access,omitempty" yaml:"remote_access,omitempty" `
	ForceLocalEndpoint bool `json:"local_endpoint,omitempty" yaml:"local_endpoint,omitempty" `
	ReportDir string `json:"report_dir" yaml:"report_dir" `
	ClusterName string `json:"cluster_name" yaml:"cluster_name" `
	License string `json:"license" yaml:"license" `
	OpsCenterURL string `json:"ops_url" yaml:"ops_url" `
	Application LocatorRef `json:"application" yaml:"application"`
	Login Login `json:"login" yaml:"login"`
	ServiceLogin ServiceLogin `json:"service_login" yaml:"service_login"`
	FlavorLabel string `json:"flavor_label" yaml:"flavor_label" `
	AWS *aws.Config `json:"aws" yaml:"aws"`
	Azure *azure.Config `json:"azure" yaml:"azure"`
	GCE *gce.Config `json:"gce" yaml:"gce"`
	Onprem *OnpremConfig `json:"onprem" yaml:"onprem"`
	Bandwagon BandwagonConfig `json:"bandwagon" yaml:"bandwagon"`
	WebDriverURL string `json:"web_driver_url,omitempty" yaml:"web_driver_url,omitempty" `
	Extensions Extensions `json:"extensions,omitempty" yaml:"extensions,omitempty"`
}
type Provisioner struct {
	Type provisionerType `json:"type" yaml:"type" `
	LoadFromState bool `json:"load_from_state" yaml:"load_from_state"`
	StateFile string `json:"state_file" yaml:"state_file"`
}
type BandwagonConfig struct {
	Organization string `json:"organization" yaml:"organization" `
	Username     string `json:"username" yaml:"username" `
	Password     string `json:"password" yaml:"password" `
	Email        string `json:"email" yaml:"email" `
	Extra        *BandwagonExtraConfig `json:"extra" yaml:"extra"`
	RemoteAccess bool
}
type BandwagonExtraConfig struct {
	PlatformDNS string `json:"platform_dns" yaml:"platform_dns"`
	NFSServer string `json:"nfs_server" yaml:"nfs_server"`
	NFSPath string `json:"nfs_path" yaml:"nfs_path"`
}
type Login struct {
	Username string `json:"username" yaml:"username"`
	Password string `json:"password" yaml:"password"`
	AuthProvider string `json:"auth_provider,omitempty" yaml:"auth_provider,omitempty"`
}
func (r Login) IsEmpty() bool {
	return r.Username == "" && r.Password == ""
}
type ServiceLogin struct {
	Username string `json:"username" yaml:"username"`
	Password string `json:"password" yaml:"password"`
}
func (r ServiceLogin) IsEmpty() bool {
	return r.Username == "" && r.Password == ""
}
type ClusterAddress struct {
	Type defaults.ClusterAddressType `json:"type" yaml:"type" validate:"eq=direct|eq=loadbalancer|eq=public"`
	Port int `json:"port,omitempty" yaml:"port,omitempty"`
}
type OnpremConfig struct {
	NumNodes int `json:"nodes" yaml:"nodes"`
	InstallerURL string `json:"installer_url" yaml:"installer_url"`
	ScriptPath string `json:"script_path" yaml:"script_path"`
	PostInstallerScript string `json:"post_installer_script" yaml:"post_installer_script"`
	ExpandProfile string `json:"expand_profile" yaml:"expand_profile"`
	OS string `json:"os" yaml:"os" validate:"required,eq=ubuntu|eq=redhat|eq=centos|eq=debian"`
	DockerDevice string `json:"docker_device" yaml:"docker_device" validate:"required"`
	ClusterAddress *ClusterAddress `json:"cluster_address" yaml:"cluster_address"`
	VarFilePath string `json:"variables_file" yaml:"variables_file"`
	OnpremProvider bool `json:"onprem_provider" yaml:"onprem_provider"`
}
func (r OnpremConfig) IsEmpty() bool {
	return r.NumNodes == 0 && r.ScriptPath == ""
}
type LocatorRef struct {
	*loc.Locator
}