diff --git a/build/serve.js b/build/serve.js index 25d89b87054e0dbdcedddf71669d030dea136fc3..3a8ff8525430999e384e88c15f76ab0e72cb96f0 100644 --- a/build/serve.js +++ b/build/serve.js @@ -89,7 +89,7 @@ gulp.task('serve', ['index'], serveDevelopmentMode); /** * Serves the application in production mode. */ -gulp.task('serve:prod', ['build-frontend', 'spawn-backend'], function () { +gulp.task('serve:prod', ['build-frontend'], function () { browserSyncInit(conf.paths.dist); }); diff --git a/src/app/backend/apiserverclient.go b/src/app/backend/apiserverclient.go new file mode 100644 index 0000000000000000000000000000000000000000..08362e900f31ac7ddf15a1c214ab0346cb386831 --- /dev/null +++ b/src/app/backend/apiserverclient.go @@ -0,0 +1,54 @@ +// Copyright 2015 Google Inc. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package backend + +import client "k8s.io/kubernetes/pkg/client/unversioned" + +// 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) { + + if apiserverHost == "" { + return clientFactory.NewInCluster() + } else { + cfg := client.Config{ + Host: apiserverHost, + } + return clientFactory.New(&cfg) + } +} + +// Default implementation of the ClientFactory. It uses k8s.io package API. +type ClientFactoryImpl struct{} + +func (ClientFactoryImpl) New(cfg *client.Config) (*client.Client, error) { + return client.New(cfg) +} + +func (ClientFactoryImpl) NewInCluster() (*client.Client, error) { + return client.NewInCluster() +} diff --git a/src/app/backend/dashboard.go b/src/app/backend/dashboard.go index 2c950a97bfbd0c82e5e8794d0f0c89a83cfeecec..fc010e4175ae3fae70c0dde850d87733394340b0 100644 --- a/src/app/backend/dashboard.go +++ b/src/app/backend/dashboard.go @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -package main +package backend import ( "flag" @@ -24,15 +24,33 @@ import ( ) var ( - argPort = pflag.Int("port", 8080, "The port to listen to for incomming HTTP requests") + argPort = pflag.Int("port", 8080, "The port to listen to for incoming HTTP requests") + argApiserverHost = pflag.String("apiserver-host", "", "The address of the Kubernetes Apiserver "+ + "to connect to in the format of protocol://address:port, e.g., "+ + "http://localhost:8001. If not specified, the assumption is that the binary runs in a"+ + "Kubernetes cluster and local discovery is attempted.") ) func main() { pflag.CommandLine.AddGoFlagSet(flag.CommandLine) + pflag.Parse() glog.Info("Starting HTTP server on port ", *argPort) defer glog.Flush() + apiserverClient, err := CreateApiserverClient(*argApiserverHost, new(ClientFactoryImpl)) + if err != nil { + glog.Fatal(err) + } + + serverAPIVersion, err := apiserverClient.ServerAPIVersions() + if err != nil { + glog.Fatal(err) + } + + // Display Apiserver version. This is just for tests. + println("Server API version: " + serverAPIVersion.GoString()) + // Run a HTTP server that serves static files from current directory. // TODO(bryk): Disable directory listing. http.Handle("/", http.FileServer(http.Dir("./"))) diff --git a/src/test/backend/apiserverclient_test.go b/src/test/backend/apiserverclient_test.go new file mode 100644 index 0000000000000000000000000000000000000000..bebb83b4a1bfce5945770e75f6a428e5cde5d2ed --- /dev/null +++ b/src/test/backend/apiserverclient_test.go @@ -0,0 +1,48 @@ +// Copyright 2015 Google Inc. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package backend + +import ( + "github.com/dashboard/src/app/backend" + client "k8s.io/kubernetes/pkg/client/unversioned" + "testing" +) + +var fakeRemoteClient = new(client.Client) +var fakeInClusterClient = new(client.Client) + +type FakeClientFactory struct{} + +func (FakeClientFactory) New(cfg *client.Config) (*client.Client, error) { + return fakeRemoteClient, nil +} + +func (FakeClientFactory) NewInCluster() (*client.Client, error) { + return fakeInClusterClient, nil +} + +func TestCreateApiserverClient_inCluster(t *testing.T) { + client, _ := backend.CreateApiserverClient("", new(FakeClientFactory)) + if client != fakeInClusterClient { + t.Fatal("Expected in cluster client to be created") + } +} + +func TestCreateApiserverClient_remote(t *testing.T) { + client, _ := backend.CreateApiserverClient("http://foo:bar", new(FakeClientFactory)) + if client != fakeRemoteClient { + t.Fatal("Expected remote client to be created") + } +}