From 39bfcfbba44061b4d9fd66ba15c0ecd2295aae72 Mon Sep 17 00:00:00 2001 From: Jonathan MacMillan Date: Tue, 21 Feb 2017 15:50:06 -0800 Subject: [PATCH] [Federation] Print out status updates while kubefed is running. --- federation/pkg/kubefed/init/BUILD | 1 + federation/pkg/kubefed/init/init.go | 50 ++++++++++++++---------- federation/pkg/kubefed/init/init_test.go | 8 ++-- 3 files changed, 35 insertions(+), 24 deletions(-) diff --git a/federation/pkg/kubefed/init/BUILD b/federation/pkg/kubefed/init/BUILD index 74568a96a01..414f26e4700 100644 --- a/federation/pkg/kubefed/init/BUILD +++ b/federation/pkg/kubefed/init/BUILD @@ -24,6 +24,7 @@ go_library( "//pkg/kubectl/cmd/templates:go_default_library", "//pkg/kubectl/cmd/util:go_default_library", "//pkg/version:go_default_library", + "//vendor/github.com/golang/glog:go_default_library", "//vendor/github.com/spf13/cobra:go_default_library", "//vendor/github.com/spf13/pflag:go_default_library", "//vendor/k8s.io/apimachinery/pkg/api/resource:go_default_library", diff --git a/federation/pkg/kubefed/init/init.go b/federation/pkg/kubefed/init/init.go index 80216f98081..c191552edff 100644 --- a/federation/pkg/kubefed/init/init.go +++ b/federation/pkg/kubefed/init/init.go @@ -51,6 +51,7 @@ import ( cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" "k8s.io/kubernetes/pkg/version" + "github.com/golang/glog" "github.com/spf13/cobra" "github.com/spf13/pflag" ) @@ -276,39 +277,41 @@ func (i *initFederation) Run(cmdOut io.Writer, config util.AdminConfig) error { } } - // 1. Create a namespace for federation system components + fmt.Fprint(cmdOut, "Creating a namespace for federation system components") _, err = createNamespace(hostClientset, i.commonOptions.Name, i.commonOptions.FederationSystemNamespace, i.options.dryRun) if err != nil { return err } + fmt.Fprint(cmdOut, " done\n") - // 2. Expose a network endpoint for the federation API server + fmt.Fprint(cmdOut, "Creating federation control plane objects (service, credentials, persistent volume claim)") svc, ips, hostnames, err := createService(hostClientset, i.commonOptions.FederationSystemNamespace, serverName, i.commonOptions.Name, i.options.apiServerAdvertiseAddress, i.options.apiServerServiceType, i.options.dryRun) if err != nil { return err } + glog.V(4).Infof("Created service named %s with IP addresses %v, hostnames %v", svc.Name, ips, hostnames) - // 3a. Generate TLS certificates and credentials, and other credentials if needed + glog.V(4).Info("Generating TLS certificates and credentials for communicating with the federation API server") credentials, err := generateCredentials(i.commonOptions.FederationSystemNamespace, i.commonOptions.Name, svc.Name, HostClusterLocalDNSZoneName, serverCredName, ips, hostnames, i.options.apiServerEnableHTTPBasicAuth, i.options.apiServerEnableTokenAuth, i.options.dryRun) if err != nil { return err } - // 3b. Create the secret containing the credentials. + // Create the secret containing the credentials. _, err = createAPIServerCredentialsSecret(hostClientset, i.commonOptions.FederationSystemNamespace, serverCredName, i.commonOptions.Name, credentials, i.options.dryRun) if err != nil { return err } + glog.V(4).Info("Certificates and credentials generated") - // 4. Create a kubeconfig secret + glog.V(4).Info("Creating an entry in the kubeconfig file with the certificate and credential data") _, err = createControllerManagerKubeconfigSecret(hostClientset, i.commonOptions.FederationSystemNamespace, i.commonOptions.Name, svc.Name, cmKubeconfigName, credentials.certEntKeyPairs, i.options.dryRun) if err != nil { return err } + glog.V(4).Info("kubeconfig successfully updated") - // 5. Create a persistent volume and a claim to store the federation - // API server's state. This is where federation API server's etcd - // stores its data. + glog.V(4).Info("Creating a persistent volume and a claim to store the federation API server's state, including etcd data") var pvc *api.PersistentVolumeClaim if i.options.etcdPersistentStorage { pvc, err = createPVC(hostClientset, i.commonOptions.FederationSystemNamespace, svc.Name, i.commonOptions.Name, i.options.etcdPVCapacity, i.options.dryRun) @@ -316,6 +319,8 @@ func (i *initFederation) Run(cmdOut io.Writer, config util.AdminConfig) error { return err } } + glog.V(4).Info("Persistent volume and claim created") + fmt.Fprint(cmdOut, " done\n") // Since only one IP address can be specified as advertise address, // we arbitrarily pick the first available IP address @@ -325,46 +330,50 @@ func (i *initFederation) Run(cmdOut io.Writer, config util.AdminConfig) error { advertiseAddress = ips[0] } - // 6. Create federation API server + fmt.Fprint(cmdOut, "Creating federation component deployments") _, err = createAPIServer(hostClientset, i.commonOptions.FederationSystemNamespace, serverName, i.commonOptions.Name, i.options.image, advertiseAddress, serverCredName, i.options.apiServerEnableHTTPBasicAuth, i.options.apiServerEnableTokenAuth, i.options.apiServerOverrides, pvc, i.options.dryRun) if err != nil { return err } + glog.V(4).Info("Successfully created federation API server") sa := &api.ServiceAccount{} sa.Name = "" - // 7. Create deployment for federation controller manager - // The below code either creates the SA and the related roles or skips - // creating the same if the RBAC support is not found in the base cluster + // Create a service account and related RBAC roles if the host cluster has RBAC support. // TODO: We must evaluate creating a separate service account even when RBAC support is missing if rbacAvailable { - // 7a. Create a service account in the host cluster for federation - // controller manager. + glog.V(4).Info("Creating service account for federation controller manager in the host cluster") sa, err = createControllerManagerSA(rbacVersionedClientset, i.commonOptions.FederationSystemNamespace, i.commonOptions.Name, i.options.dryRun) if err != nil { return err } + glog.V(4).Info("Successfully created federation controller manager service account") - // 7b. Create RBAC role and role binding for federation controller - // manager service account. + glog.V(4).Info("Creating RBAC role and role bindings for the federation controller manager's service account") _, _, err = createRoleBindings(rbacVersionedClientset, i.commonOptions.FederationSystemNamespace, sa.Name, i.commonOptions.Name, i.options.dryRun) if err != nil { return err } + glog.V(4).Info("Successfully created RBAC role and role bindings") } - // 7c. Create a dns-provider config secret + glog.V(4).Info("Creating a DNS provider config secret") dnsProviderSecret, err := createDNSProviderConfigSecret(hostClientset, i.commonOptions.FederationSystemNamespace, dnsProviderSecretName, i.commonOptions.Name, dnsProviderConfigBytes, i.options.dryRun) if err != nil { return err } + glog.V(4).Info("Successfully created DNS provider config secret") + + glog.V(4).Info("Creating federation controller manager deployment") - // 7d. Create federation controller manager deployment. _, err = createControllerManager(hostClientset, i.commonOptions.FederationSystemNamespace, i.commonOptions.Name, svc.Name, cmName, i.options.image, cmKubeconfigName, i.options.dnsZoneName, i.options.dnsProvider, sa.Name, dnsProviderSecret, i.options.controllerManagerOverrides, i.options.dryRun) if err != nil { return err } + glog.V(4).Info("Successfully created federation controller manager deployment") + fmt.Fprint(cmdOut, " done\n") + fmt.Fprint(cmdOut, "Updating kubeconfig ") // Pick the first ip/hostname to update the api server endpoint in kubeconfig and also to give information to user // In case of NodePort Service for api server, ips are node external ips. endpoint := "" @@ -378,20 +387,21 @@ func (i *initFederation) Run(cmdOut io.Writer, config util.AdminConfig) error { endpoint = endpoint + ":" + strconv.Itoa(int(svc.Spec.Ports[0].NodePort)) } - // 8. Write the federation API server endpoint info, credentials - // and context to kubeconfig err = updateKubeconfig(config, i.commonOptions.Name, endpoint, i.commonOptions.Kubeconfig, credentials, i.options.dryRun) if err != nil { return err } + fmt.Fprint(cmdOut, " done\n") if !i.options.dryRun { + fmt.Fprint(cmdOut, "Waiting for federation control plane to come up ") fedPods := []string{serverName, cmName} err = waitForPods(hostClientset, fedPods, i.commonOptions.FederationSystemNamespace) if err != nil { return err } err = waitSrvHealthy(config, i.commonOptions.Name, i.commonOptions.Kubeconfig) + fmt.Fprint(cmdOut, " done\n") if err != nil { return err } diff --git a/federation/pkg/kubefed/init/init_test.go b/federation/pkg/kubefed/init/init_test.go index 64894360d7b..f09d44010bd 100644 --- a/federation/pkg/kubefed/init/init_test.go +++ b/federation/pkg/kubefed/init/init_test.go @@ -276,13 +276,13 @@ func TestInitFederation(t *testing.T) { // Actual data passed are tested in the fake secret and cluster // REST clients. endpoint := getEndpoint(tc.apiserverServiceType, tc.lbIP, tc.advertiseAddress) - want := fmt.Sprintf("Federation API server is running at: %s\n", endpoint) + wantedSuffix := fmt.Sprintf("Federation API server is running at: %s\n", endpoint) if tc.dryRun != "" { - want = fmt.Sprintf("Federation control plane runs (dry run)\n") + wantedSuffix = fmt.Sprintf("Federation control plane runs (dry run)\n") } - if got := buf.String(); got != want { - t.Errorf("[%d] unexpected output: got: %s, want: %s", i, got, want) + if got := buf.String(); !strings.HasSuffix(got, wantedSuffix) { + t.Errorf("[%d] unexpected output: got: %s, wanted suffix: %s", i, got, wantedSuffix) if cmdErrMsg != "" { t.Errorf("[%d] unexpected error message: %s", i, cmdErrMsg) }