in app/testing/testserver.go [63:201]
func StartTestServer(t Logger, customFlags []string) (result TestServer, err error) {
stopCh := make(chan struct{})
configDoneCh := make(chan struct{})
var capturedConfig config.CompletedConfig
tearDown := func() {
close(stopCh)
if len(result.TmpDir) != 0 {
os.RemoveAll(result.TmpDir)
}
}
defer func() {
if result.TearDownFn == nil {
tearDown()
}
}()
result.TmpDir, err = ioutil.TempDir("", "cloud-controller-manager")
if err != nil {
return result, fmt.Errorf("failed to create temp dir: %v", err)
}
s, err := options.NewCloudControllerManagerOptions()
if err != nil {
return TestServer{}, err
}
cloudInitializer := func(config *config.CompletedConfig) cloudprovider.Interface {
capturedConfig = *config
// send signal to indicate the capturedConfig has been properly set
close(configDoneCh)
cloudConfig := config.ComponentConfig.KubeCloudShared.CloudProvider
cloud, err := cloudprovider.InitCloudProvider(cloudConfig.Name, cloudConfig.CloudConfigFile)
if err != nil {
t.Fatalf("Cloud provider could not be initialized: %v", err)
}
s.SecureServing.ServerCert.CertDirectory = result.TmpDir
if cloud == nil {
t.Fatalf("Cloud provider is nil")
}
return cloud
}
fss := cliflag.NamedFlagSets{}
command := app.NewCloudControllerManagerCommand(s, cloudInitializer, app.DefaultInitFuncConstructors, fss, stopCh)
commandArgs := []string{}
listeners := []net.Listener{}
disableInsecure := false
disableSecure := false
for _, arg := range customFlags {
if strings.HasPrefix(arg, "--secure-port=") {
if arg == "--secure-port=0" {
commandArgs = append(commandArgs, arg)
disableSecure = true
}
} else if strings.HasPrefix(arg, "--port=") {
if arg == "--port=0" {
commandArgs = append(commandArgs, arg)
disableInsecure = true
}
} else if strings.HasPrefix(arg, "--cert-dir=") {
// skip it
} else {
commandArgs = append(commandArgs, arg)
}
}
if !disableSecure {
listener, bindPort, err := createListenerOnFreePort()
if err != nil {
return result, fmt.Errorf("failed to create listener: %v", err)
}
listeners = append(listeners, listener)
commandArgs = append(commandArgs, fmt.Sprintf("--secure-port=%d", bindPort))
commandArgs = append(commandArgs, fmt.Sprintf("--cert-dir=%s", result.TmpDir))
t.Logf("cloud-controller-manager will listen securely on port %d...", bindPort)
}
if !disableInsecure {
listener, bindPort, err := createListenerOnFreePort()
if err != nil {
return result, fmt.Errorf("failed to create listener: %v", err)
}
listeners = append(listeners, listener)
commandArgs = append(commandArgs, fmt.Sprintf("--port=%d", bindPort))
t.Logf("cloud-controller-manager will listen securely on port %d...", bindPort)
}
for _, listener := range listeners {
listener.Close()
}
errCh := make(chan error)
go func() {
command.SetArgs(commandArgs)
if err := command.Execute(); err != nil {
errCh <- err
}
close(errCh)
}()
select {
case <-configDoneCh:
case err := <-errCh:
return result, err
}
t.Logf("Waiting for /healthz to be ok...")
client, err := kubernetes.NewForConfig(capturedConfig.LoopbackClientConfig)
if err != nil {
return result, fmt.Errorf("failed to create a client: %v", err)
}
err = wait.Poll(100*time.Millisecond, 30*time.Second, func() (bool, error) {
select {
case err := <-errCh:
return false, err
default:
}
result := client.CoreV1().RESTClient().Get().AbsPath("/healthz").Do(context.TODO())
status := 0
result.StatusCode(&status)
if status == 200 {
return true, nil
}
return false, nil
})
if err != nil {
return result, fmt.Errorf("failed to wait for /healthz to return ok: %v", err)
}
// from here the caller must call tearDown
result.LoopbackClientConfig = capturedConfig.LoopbackClientConfig
result.Options = s
result.Config = &capturedConfig
result.TearDownFn = tearDown
return result, nil
}