提交 f3ba5780 编写于 作者: P Piotr Bryk

Merge branch 'master' into package.json

......@@ -41,16 +41,6 @@ before_script:
- export DISPLAY=:99.0
- sh -e /etc/init.d/xvfb start
# Install frontend dependencies to be able to build the project.
- ./node_modules/.bin/bower install
# Set up Go environment for build.
- export GOPATH=$HOME/.gopath
# Download godep tool and make add it to PATH environment variable.
- go get github.com/tools/godep
- export PATH=$PATH:$GOPATH/bin
# Download etcd and make add it to PATH environment variable.
# Etcd is used to manage kubernetes cluster coordination and for state management.
- curl -fsSL https://github.com/coreos/etcd/releases/download/v2.2.1/etcd-v2.2.1-linux-amd64.tar.gz | tar xzf -
......@@ -59,6 +49,6 @@ before_script:
# Pull golang image to build local kubernetes cluster.
# Local cluster has build process that runs in a Docker container.
# This simplifies initial set up and provides for a very consistent build and test environment.
# This simplifies initial set up and provides a very consistent build and test environment.
- docker pull golang:1.4
script: ./node_modules/.bin/gulp check:create-cluster
......@@ -8,7 +8,7 @@
"angular": "~1.4.2",
"angular-animate": "~1.4.2",
"angular-aria": "~1.4.2",
"angular-material": "~0.11.4",
"angular-material": "~1.0.0-rc6",
"angular-messages": "~1.4.2",
"angular-ui-router": "~0.2.15",
"angular-resource": "~1.4.2",
......
#!/bin/bash
# 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.
# This is a script that runs on npm install postinstall phase.
# It contains all prerequisites required to use the build system.
./node_modules/.bin/bower install
# Godep is required by the project. Install it in the tools directory.
GOPATH=`pwd`/.tools/go go get github.com/tools/godep
......@@ -9,9 +9,9 @@
"license": "Apache-2.0",
"devDependencies": {
"babel": "~6.1.18",
"babel-core": "~6.2.1",
"babel-core": "~6.3.13",
"babel-loader": "~6.2.0",
"babel-preset-es2015": "~6.1.18",
"babel-preset-es2015": "~6.3.13",
"babelify": "~7.2.0",
"bower": "~1.6.5",
"browser-sync": "~2.10.0",
......@@ -73,7 +73,6 @@
"node": ">=4.2.2"
},
"scripts": {
"postinstall": "./node_modules/.bin/bower install",
"postinstall": "export GOPATH=`pwd`/.tools/go && go get github.com/tools/godep"
"postinstall": "./build/postinstall.sh"
}
}
......@@ -160,6 +160,7 @@ func getServicePortsName(ports []api.ServicePort) string {
// Returns all services that target the same Pods (or subset) as the given Replica Set.
func getMatchingServices(services []api.Service,
replicaSet *api.ReplicationController) []api.Service {
// TODO(bryk): Match namespace too.
var matchingServices []api.Service
for _, service := range services {
......
......@@ -17,9 +17,9 @@ limitations under the License.
<md-content class="kd-content">
<md-toolbar class="kd-toolbar">
<div class="md-toolbar-tools">
<md-button ui-sref="zero" aria-label="Kubernetes Dashboard homepage" class="md-icon-button">
<a ui-sref="zero">
<md-icon md-svg-icon="assets/images/kubernetes-logo.svg" class="kd-toolbar-logo"></md-icon>
</md-button>
</a>
<h2>
<span>kubernetes</span>
</h2>
......
......@@ -15,6 +15,7 @@
.kd-toolbar-logo {
height: 42px;
width: 42px;
margin-right: 1em;
}
.kd-toolbar {
......
......@@ -24,10 +24,10 @@ limitations under the License.
<label>Namespace name</label>
<input ng-model="ctrl.namespace" required>
</md-input-container>
<div class="md-actions" layout="row">
<md-dialog-actions layout="row">
<md-button ng-disabled="ctrl.isDisabled()" class="md-primary" type="submit">OK</md-button>
<md-button ng-click="ctrl.cancel()">Cancel</md-button>
</div>
</md-dialog-actions>
</form>
</md-content>
</md-dialog>
......@@ -29,7 +29,7 @@ limitations under the License.
</span>
</div>
</div>
<md-button flex="none" class="md-icon-button">
<md-button class="md-icon-button">
<md-icon md-font-library="material-icons">more_vert</md-icon>
</md-button>
</div>
......
......@@ -15,10 +15,194 @@
package main
import (
"k8s.io/kubernetes/pkg/api"
"reflect"
"testing"
)
func TestFoo(t *testing.T) {
// TODO(bryk): Write tests here.
isServiceMatchingReplicaSet(nil, nil)
func TestIsServiceMatchingReplicaSet(t *testing.T) {
cases := []struct {
serviceSelector, replicaSetSelector map[string]string
expected bool
}{
{nil, nil, false},
{nil, map[string]string{}, false},
{map[string]string{}, nil, false},
{map[string]string{}, map[string]string{}, false},
{map[string]string{"app": "my-name"}, map[string]string{}, false},
{map[string]string{"app": "my-name", "version": "2"},
map[string]string{"app": "my-name", "version": "1.1"}, false},
{map[string]string{"app": "my-name", "env": "prod"},
map[string]string{"app": "my-name", "version": "1.1"}, false},
{map[string]string{"app": "my-name"}, map[string]string{"app": "my-name"}, true},
{map[string]string{"app": "my-name", "version": "1.1"},
map[string]string{"app": "my-name", "version": "1.1"}, true},
{map[string]string{"app": "my-name"},
map[string]string{"app": "my-name", "version": "1.1"}, true},
}
for _, c := range cases {
actual := isServiceMatchingReplicaSet(c.serviceSelector, c.replicaSetSelector)
if actual != c.expected {
t.Errorf("isServiceMatchingReplicaSet(%+v, %+v) == %+v, expected %+v",
c.serviceSelector, c.replicaSetSelector, actual, c.expected)
}
}
}
func TestGetServicePortsName(t *testing.T) {
cases := []struct {
ports []api.ServicePort
expected string
}{
{nil, ""},
{[]api.ServicePort{}, ""},
{[]api.ServicePort{{Name: "foo", Port: 8080, Protocol: "TCP"}}, " 8080/TCP"},
{[]api.ServicePort{{Name: "foo", Port: 8080, Protocol: "TCP"},
{Name: "foo", Port: 9191, Protocol: "UDP"}}, " 8080/TCP,9191/UDP"},
}
for _, c := range cases {
actual := getServicePortsName(c.ports)
if actual != c.expected {
t.Errorf("getServicePortsName(%+v) == %+v, expected %+v", c.ports, actual, c.expected)
}
}
}
func TestGetExternalEndpoint(t *testing.T) {
cases := []struct {
serviceIp string
ports []api.ServicePort
expected string
}{
{"127.0.0.1", nil, "127.0.0.1"},
{"127.0.0.1", []api.ServicePort{{Name: "foo", Port: 8080, Protocol: "TCP"}},
"127.0.0.1 8080/TCP"},
}
for _, c := range cases {
actual := getExternalEndpoint(c.serviceIp, c.ports)
if actual != c.expected {
t.Errorf("getExternalEndpoint(%+v, %+v) == %+v, expected %+v",
c.serviceIp, c.ports, actual, c.expected)
}
}
}
func TestGetInternalEndpoint(t *testing.T) {
cases := []struct {
serviceName, namespace string
ports []api.ServicePort
expected string
}{
{"my-service", api.NamespaceDefault, nil, "my-service"},
{"my-service", api.NamespaceDefault,
[]api.ServicePort{{Name: "foo", Port: 8080, Protocol: "TCP"}},
"my-service 8080/TCP"},
{"my-service", "my-namespace", nil, "my-service.my-namespace"},
{"my-service", "my-namespace",
[]api.ServicePort{{Name: "foo", Port: 8080, Protocol: "TCP"}},
"my-service.my-namespace 8080/TCP"},
}
for _, c := range cases {
actual := getInternalEndpoint(c.serviceName, c.namespace, c.ports)
if actual != c.expected {
t.Errorf("getInternalEndpoint(%+v, %+v, %+v) == %+v, expected %+v",
c.serviceName, c.namespace, c.ports, actual, c.expected)
}
}
}
func TestGetMatchingServices(t *testing.T) {
cases := []struct {
services []api.Service
replicaSet *api.ReplicationController
expected []api.Service
}{
{nil, nil, nil},
{
[]api.Service{{Spec: api.ServiceSpec{Selector: map[string]string{"app": "my-name"}}}},
&api.ReplicationController{
Spec: api.ReplicationControllerSpec{Selector: map[string]string{"app": "my-name"}}},
[]api.Service{{Spec: api.ServiceSpec{Selector: map[string]string{"app": "my-name"}}}},
},
{
[]api.Service{
{Spec: api.ServiceSpec{Selector: map[string]string{"app": "my-name"}}},
{Spec: api.ServiceSpec{Selector: map[string]string{"app": "my-name", "ver": "2"}}},
},
&api.ReplicationController{
Spec: api.ReplicationControllerSpec{Selector: map[string]string{"app": "my-name"}}},
[]api.Service{{Spec: api.ServiceSpec{Selector: map[string]string{"app": "my-name"}}}},
},
}
for _, c := range cases {
actual := getMatchingServices(c.services, c.replicaSet)
if !reflect.DeepEqual(actual, c.expected) {
t.Errorf("getMatchingServices(%+v, %+v) == %+v, expected %+v",
c.services, c.replicaSet, actual, c.expected)
}
}
}
func TestGetReplicaSetList(t *testing.T) {
cases := []struct {
replicaSets []api.ReplicationController
services []api.Service
expected *ReplicaSetList
}{
{nil, nil, &ReplicaSetList{}},
{
[]api.ReplicationController{
{
Spec: api.ReplicationControllerSpec{
Selector: map[string]string{"app": "my-name-1"},
Template: &api.PodTemplateSpec{
Spec: api.PodSpec{Containers: []api.Container{{Image: "my-container-image-1"}}},
},
},
},
{
Spec: api.ReplicationControllerSpec{
Selector: map[string]string{"app": "my-name-2", "ver": "2"},
Template: &api.PodTemplateSpec{
Spec: api.PodSpec{Containers: []api.Container{{Image: "my-container-image-2"}}},
},
},
},
},
[]api.Service{
{
Spec: api.ServiceSpec{Selector: map[string]string{"app": "my-name-1"}},
ObjectMeta: api.ObjectMeta{
Name: "my-app-1",
Namespace: "namespace-1",
},
},
{
Spec: api.ServiceSpec{Selector: map[string]string{"app": "my-name-2", "ver": "2"}},
ObjectMeta: api.ObjectMeta{
Name: "my-app-2",
Namespace: "namespace-2",
},
},
},
&ReplicaSetList{
ReplicaSets: []ReplicaSet{
{
ContainerImages: []string{"my-container-image-1"},
InternalEndpoints: []string{"my-app-1.namespace-1"},
}, {
ContainerImages: []string{"my-container-image-2"},
InternalEndpoints: []string{"my-app-2.namespace-2"},
},
},
},
},
}
for _, c := range cases {
actual := getReplicaSetList(c.replicaSets, c.services)
if !reflect.DeepEqual(actual, c.expected) {
t.Errorf("getReplicaSetList(%#v, %#v) == %#v, expected %#v",
c.replicaSets, c.services, actual, c.expected)
}
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册