Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 10 additions & 5 deletions src/app/backend/apihandler.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import (

restful "github.com/emicklei/go-restful"
client "k8s.io/kubernetes/pkg/client/unversioned"
"k8s.io/kubernetes/pkg/client/unversioned/clientcmd"
)

const (
Expand Down Expand Up @@ -55,8 +56,10 @@ func FormatResponseLog(resp *restful.Response, req *restful.Request) string {
}

// Creates a new HTTP handler that handles all requests to the API of the backend.
func CreateHttpApiHandler(client *client.Client, heapsterClient HeapsterClient) http.Handler {
apiHandler := ApiHandler{client, heapsterClient}
func CreateHttpApiHandler(client *client.Client, heapsterClient HeapsterClient,
clientConfig clientcmd.ClientConfig) http.Handler {

apiHandler := ApiHandler{client, heapsterClient, clientConfig}
wsContainer := restful.NewContainer()

deployWs := new(restful.WebService)
Expand Down Expand Up @@ -181,6 +184,7 @@ func CreateHttpApiHandler(client *client.Client, heapsterClient HeapsterClient)
type ApiHandler struct {
client *client.Client
heapsterClient HeapsterClient
clientConfig clientcmd.ClientConfig
}

// Handles deploy API call.
Expand All @@ -206,7 +210,8 @@ func (apiHandler *ApiHandler) handleDeployFromFile(request *restful.Request, res
return
}

isDeployed, err := DeployAppFromFile(deploymentSpec, CreateObjectFromInfoFn)
isDeployed, err := DeployAppFromFile(
deploymentSpec, CreateObjectFromInfoFn, apiHandler.clientConfig)
if !isDeployed {
handleInternalError(response, err)
return
Expand All @@ -218,9 +223,9 @@ func (apiHandler *ApiHandler) handleDeployFromFile(request *restful.Request, res
}

response.WriteHeaderAndEntity(http.StatusCreated, AppDeploymentFromFileResponse{
Name: deploymentSpec.Name,
Name: deploymentSpec.Name,
Content: deploymentSpec.Content,
Error: errorMessage,
Error: errorMessage,
})
}

Expand Down
58 changes: 29 additions & 29 deletions src/app/backend/apiserverclient.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,42 +18,42 @@ import (
"log"

client "k8s.io/kubernetes/pkg/client/unversioned"
"k8s.io/kubernetes/pkg/client/unversioned/clientcmd"
clientcmdapi "k8s.io/kubernetes/pkg/client/unversioned/clientcmd/api"
)

// Factory that creates Kubernetes API clients.
type ClientFactory interface {
// Creates new API client assuming that the binary runs in a cluster.
NewInCluster() (*client.Client, error)

// Creates new API client from the given config.
New(*client.Config) (*client.Client, error)
}

// Creates new Kubernetes Apiserver client. When apiserverHost param is empty string the function
// assumes that it is running inside a Kubernetes cluster and attempts to discover the Apiserver.
// Otherwise, it connects to the Apiserver specified.
// apiserverHost param is in the format of protocol://address:port, e.g., http://localhost:8001.
func CreateApiserverClient(apiserverHost string,
clientFactory ClientFactory) (*client.Client, error) {
log.Printf("Creating API client for %s", apiserverHost)

if apiserverHost == "" {
return clientFactory.NewInCluster()
} else {
cfg := client.Config{
Host: apiserverHost,
}
return clientFactory.New(&cfg)
//
// apiserverHost param is in the format of protocol://address:port/pathPrefix, e.g.,
// http://localhost:8001.
//
// Returns created client and its configuration.
func CreateApiserverClient(apiserverHost string) (*client.Client, clientcmd.ClientConfig, error) {

overrides := &clientcmd.ConfigOverrides{}

if apiserverHost != "" {
overrides.ClusterInfo = clientcmdapi.Cluster{Server: apiserverHost}
}
}

// Default implementation of the ClientFactory. It uses k8s.io package API.
type ClientFactoryImpl struct{}
clientConfig := clientcmd.NewNonInteractiveDeferredLoadingClientConfig(
&clientcmd.ClientConfigLoadingRules{}, overrides)

func (ClientFactoryImpl) New(cfg *client.Config) (*client.Client, error) {
return client.New(cfg)
}
cfg, err := clientConfig.ClientConfig()

if err != nil {
return nil, nil, err
}

log.Printf("Creating API server client for %s", cfg.Host)

client, err := client.New(cfg)

if err != nil {
return nil, nil, err
}

func (ClientFactoryImpl) NewInCluster() (*client.Client, error) {
return client.NewInCluster()
return client, clientConfig, nil
}
4 changes: 2 additions & 2 deletions src/app/backend/dashboard.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ func main() {

log.Printf("Starting HTTP server on port %d", *argPort)

apiserverClient, err := CreateApiserverClient(*argApiserverHost, new(ClientFactoryImpl))
apiserverClient, config, err := CreateApiserverClient(*argApiserverHost)
if err != nil {
log.Fatalf("Error while initializing connection to Kubernetes master: %s. Quitting.", err)
}
Expand All @@ -54,6 +54,6 @@ func main() {
// Run a HTTP server that serves static public files from './public' and handles API calls.
// TODO(bryk): Disable directory listing.
http.Handle("/", http.FileServer(http.Dir("./public")))
http.Handle("/api/", CreateHttpApiHandler(apiserverClient, heapsterRESTClient))
http.Handle("/api/", CreateHttpApiHandler(apiserverClient, heapsterRESTClient, config))
log.Print(http.ListenAndServe(fmt.Sprintf(":%d", *argPort), nil))
}
12 changes: 7 additions & 5 deletions src/app/backend/deploy.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import (
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api/resource"
client "k8s.io/kubernetes/pkg/client/unversioned"
"k8s.io/kubernetes/pkg/client/unversioned/clientcmd"
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
kubectlResource "k8s.io/kubernetes/pkg/kubectl/resource"
"k8s.io/kubernetes/pkg/util/intstr"
Expand Down Expand Up @@ -281,17 +282,18 @@ type createObjectFromInfo func(info *kubectlResource.Info) (bool, error)
// Implementation of createObjectFromInfo
func CreateObjectFromInfoFn(info *kubectlResource.Info) (bool, error) {
createdResource, err := kubectlResource.NewHelper(info.Client, info.Mapping).Create(info.Namespace, true, info.Object)
return createdResource != nil , err
return createdResource != nil, err
}

// Deploys an app based on the given yaml or json file.
func DeployAppFromFile(spec *AppDeploymentFromFileSpec, createObjectFromInfoFn createObjectFromInfo) (bool, error) {
func DeployAppFromFile(spec *AppDeploymentFromFileSpec,
createObjectFromInfoFn createObjectFromInfo, clientConfig clientcmd.ClientConfig) (bool, error) {
const (
validate = true
emptyCacheDir = ""
)

factory := cmdutil.NewFactory(nil)
factory := cmdutil.NewFactory(clientConfig)
schema, err := factory.Validator(validate, emptyCacheDir)
if err != nil {
return false, err
Expand All @@ -307,12 +309,12 @@ func DeployAppFromFile(spec *AppDeploymentFromFileSpec, createObjectFromInfoFn c
Flatten().
Do()

deployedResourcesCount:= 0
deployedResourcesCount := 0

err = r.Visit(func(info *kubectlResource.Info, err error) error {
isDeployed, err := createObjectFromInfoFn(info)
if isDeployed {
deployedResourcesCount ++
deployedResourcesCount++
log.Printf("%s is deployed", info.Name)
}
return err
Expand Down
48 changes: 0 additions & 48 deletions src/test/backend/apiserverclient_test.go

This file was deleted.

4 changes: 2 additions & 2 deletions src/test/backend/deploy_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,7 @@ func TestDeployAppFromFileWithValidContent(t *testing.T) {
}
fakeCreateObjectFromInfo := func(info *kubectlResource.Info) (bool, error) { return true, nil }

isDeployed, err := DeployAppFromFile(spec, fakeCreateObjectFromInfo)
isDeployed, err := DeployAppFromFile(spec, fakeCreateObjectFromInfo, nil)
if err != nil {
t.Errorf("Expected return value to have %#v but got %#v", nil, err)
}
Expand All @@ -210,7 +210,7 @@ func TestDeployAppFromFileWithInvalidContent(t *testing.T) {
// return is set to true to check if the validation prior to this function really works
fakeCreateObjectFromInfo := func(info *kubectlResource.Info) (bool, error) { return true, nil }

isDeployed, err := DeployAppFromFile(spec, fakeCreateObjectFromInfo)
isDeployed, err := DeployAppFromFile(spec, fakeCreateObjectFromInfo, nil)
if err == nil {
t.Errorf("Expected return value to have an error but got %#v", nil)
}
Expand Down