Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
凌波微步_大先生
dashboard
提交
d6c3b563
D
dashboard
项目概览
凌波微步_大先生
/
dashboard
与 Fork 源项目一致
从无法访问的项目Fork
通知
2
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
D
dashboard
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
d6c3b563
编写于
12月 01, 2015
作者:
P
Piotr Bryk
浏览文件
操作
浏览文件
下载
差异文件
Merge pull request #99 from bryk/match-service
Replica set list: handle endpoints and descirption
上级
863df6d1
f62b4688
变更
14
隐藏空白更改
内联
并排
Showing
14 changed file
with
225 addition
and
86 deletion
+225
-86
build/backend.js
build/backend.js
+15
-2
build/conf.js
build/conf.js
+2
-5
build/gocommand.js
build/gocommand.js
+3
-2
build/test.js
build/test.js
+11
-16
src/app/backend/apihandler.go
src/app/backend/apihandler.go
+1
-1
src/app/backend/deploy.go
src/app/backend/deploy.go
+21
-12
src/app/backend/namespaces.go
src/app/backend/namespaces.go
+3
-3
src/app/backend/replicasetlist.go
src/app/backend/replicasetlist.go
+104
-18
src/app/externs/backendapi.js
src/app/externs/backendapi.js
+1
-0
src/app/frontend/deploy/deploy.html
src/app/frontend/deploy/deploy.html
+11
-7
src/app/frontend/deploy/deploy_controller.js
src/app/frontend/deploy/deploy_controller.js
+4
-0
src/app/frontend/replicasetlist/replicasetlist.html
src/app/frontend/replicasetlist/replicasetlist.html
+23
-17
src/test/backend/apiserverclient_test.go
src/test/backend/apiserverclient_test.go
+2
-3
src/test/backend/replicasetlist_test.go
src/test/backend/replicasetlist_test.go
+24
-0
未找到文件。
build/backend.js
浏览文件 @
d6c3b563
...
...
@@ -26,7 +26,7 @@ import goCommand from './gocommand';
* Compiles backend application in development mode and places the binary in the serve
* directory.
*/
gulp
.
task
(
'
backend
'
,
function
(
doneFn
)
{
gulp
.
task
(
'
backend
'
,
[
'
package-backend-source
'
],
function
(
doneFn
)
{
goCommand
(
[
'
build
'
,
...
...
@@ -46,7 +46,7 @@ gulp.task('backend', function(doneFn) {
* The production binary difference from development binary is only that it contains all
* dependencies inside it and is targeted for Linux.
*/
gulp
.
task
(
'
backend:prod
'
,
function
(
doneFn
)
{
gulp
.
task
(
'
backend:prod
'
,
[
'
package-backend-source
'
],
function
(
doneFn
)
{
let
outputBinaryPath
=
path
.
join
(
conf
.
paths
.
dist
,
conf
.
backend
.
binaryName
);
// Delete output binary first. This is required because prod build does not override it.
...
...
@@ -72,3 +72,16 @@ gulp.task('backend:prod', function(doneFn) {
},
function
(
error
)
{
doneFn
(
error
);
});
});
/**
* Moves all backend source files (app and tests) to a temporary package directory where it can be
* applied go commands.
*
* This is required to consolidate test and app files into single directories and to make packaging
* work.
*/
gulp
.
task
(
'
package-backend-source
'
,
function
()
{
return
gulp
.
src
([
path
.
join
(
conf
.
paths
.
backendSrc
,
'
**/*
'
),
path
.
join
(
conf
.
paths
.
backendTest
,
'
**/*
'
)])
.
pipe
(
gulp
.
dest
(
conf
.
paths
.
backendTmpSrc
));
});
build/conf.js
浏览文件 @
d6c3b563
...
...
@@ -37,11 +37,7 @@ export default {
/**
* Name of the main backend package that is used in go build command.
*/
packageName
:
'
app/backend
'
,
/**
* Name of the test backend package that is used in go test command.
*/
testPackageName
:
'
test/backend
'
,
packageName
:
'
github.com/kubernetes/dashboard
'
,
/**
* Port number of the backend server. Only used during development.
*/
...
...
@@ -86,6 +82,7 @@ export default {
backendSrc
:
path
.
join
(
basePath
,
'
src/app/backend
'
),
backendTest
:
path
.
join
(
basePath
,
'
src/test/backend
'
),
backendTmp
:
path
.
join
(
basePath
,
'
.tmp/backend
'
),
backendTmpSrc
:
path
.
join
(
basePath
,
'
.tmp/backend/src/github.com/kubernetes/dashboard
'
),
bowerComponents
:
path
.
join
(
basePath
,
'
bower_components
'
),
build
:
path
.
join
(
basePath
,
'
build
'
),
deploySrc
:
path
.
join
(
basePath
,
'
src/app/deploy
'
),
...
...
build/gocommand.js
浏览文件 @
d6c3b563
...
...
@@ -21,7 +21,8 @@ import lodash from 'lodash';
import
conf
from
'
./conf
'
;
/**
* Spawns Go process wrapped with the Godep command.
* Spawns Go process wrapped with the Godep command. Backend source files must me packaged with
* 'package-backend-source' task before running this command.
*
* @param {!Array<string>} args
* @param {function(?Error=)} doneFn
...
...
@@ -33,7 +34,7 @@ export default function spawnGoProcess(args, doneFn) {
return
;
}
let
sourceGopath
=
`
${
process
.
env
.
GOPATH
}
:
${
conf
.
paths
.
ba
se
}
`
;
let
sourceGopath
=
`
${
process
.
env
.
GOPATH
}
:
${
conf
.
paths
.
ba
ckendTmp
}
`
;
let
env
=
lodash
.
merge
(
process
.
env
,
{
GOPATH
:
sourceGopath
});
let
goTask
=
child
.
spawn
(
'
godep
'
,
[
'
go
'
].
concat
(
args
),
{
...
...
build/test.js
浏览文件 @
d6c3b563
...
...
@@ -28,7 +28,7 @@ import goCommand from './gocommand';
* @param {boolean} singleRun
* @param {function(?Error=)} doneFn
*/
function
runUnitTests
(
singleRun
,
doneFn
)
{
function
run
Frontend
UnitTests
(
singleRun
,
doneFn
)
{
let
localConfig
=
{
configFile
:
conf
.
paths
.
karmaConf
,
singleRun
:
singleRun
,
...
...
@@ -41,18 +41,6 @@ function runUnitTests(singleRun, doneFn) {
server
.
start
();
}
/**
* @param {function(?Error=)} doneFn
*/
function
runBackendTests
(
doneFn
)
{
goCommand
(
[
'
test
'
,
conf
.
backend
.
testPackageName
,
],
doneFn
);
}
/**
* @param {function(?Error=)} doneFn
*/
...
...
@@ -86,12 +74,19 @@ gulp.task('test', ['frontend-test', 'backend-test']);
/**
* Runs once all unit tests of the frontend application.
*/
gulp
.
task
(
'
frontend-test
'
,
function
(
doneFn
)
{
runUnitTests
(
true
,
doneFn
);
});
gulp
.
task
(
'
frontend-test
'
,
function
(
doneFn
)
{
run
Frontend
UnitTests
(
true
,
doneFn
);
});
/**
* Runs once all unit tests of the backend application.
*/
gulp
.
task
(
'
backend-test
'
,
runBackendTests
);
gulp
.
task
(
'
backend-test
'
,
[
'
package-backend-source
'
],
function
(
doneFn
)
{
goCommand
(
[
'
test
'
,
conf
.
backend
.
packageName
,
],
doneFn
);
});
/**
* Runs all unit tests of the application. Watches for changes in the source files to rerun
...
...
@@ -103,7 +98,7 @@ gulp.task('test:watch', ['frontend-test:watch', 'backend-test:watch']);
* Runs frontend backend application tests. Watches for changes in the source files to rerun
* the tests.
*/
gulp
.
task
(
'
frontend-test:watch
'
,
function
(
doneFn
)
{
runUnitTests
(
false
,
doneFn
);
});
gulp
.
task
(
'
frontend-test:watch
'
,
function
(
doneFn
)
{
run
Frontend
UnitTests
(
false
,
doneFn
);
});
/**
* Runs backend application tests. Watches for changes in the source files to rerun
...
...
src/app/backend/apihandler.go
浏览文件 @
d6c3b563
...
...
@@ -62,7 +62,7 @@ func CreateHttpApiHandler(client *client.Client) http.Handler {
namespacesWs
.
Route
(
namespacesWs
.
GET
(
""
)
.
To
(
apiHandler
.
handleGetNamespaces
)
.
Writes
(
Namespace
s
List
{}))
Writes
(
NamespaceList
{}))
wsContainer
.
Add
(
namespacesWs
)
logsWs
:=
new
(
restful
.
WebService
)
...
...
src/app/backend/deploy.go
浏览文件 @
d6c3b563
...
...
@@ -20,6 +20,11 @@ import (
"k8s.io/kubernetes/pkg/util"
)
const
(
DescriptionAnnotationKey
=
"description"
NameLabelKey
=
"name"
)
// Specification for an app deployment.
type
AppDeploymentSpec
struct
{
// Name of the application.
...
...
@@ -38,6 +43,9 @@ type AppDeploymentSpec struct {
// Whether the created service is external.
IsExternal
bool
`json:"isExternal"`
// Description of the deployment.
Description
string
`json:"description"`
// Target namespace of the application.
Namespace
string
`json:"namespace"`
}
...
...
@@ -59,10 +67,16 @@ type PortMapping struct {
// common labels.
// TODO(bryk): Write tests for this function.
func
DeployApp
(
spec
*
AppDeploymentSpec
,
client
*
client
.
Client
)
error
{
annotations
:=
map
[
string
]
string
{
DescriptionAnnotationKey
:
spec
.
Description
}
labels
:=
map
[
string
]
string
{
NameLabelKey
:
spec
.
Name
}
objectMeta
:=
api
.
ObjectMeta
{
Annotations
:
annotations
,
Name
:
spec
.
Name
,
Labels
:
labels
,
}
podTemplate
:=
&
api
.
PodTemplateSpec
{
ObjectMeta
:
api
.
ObjectMeta
{
Labels
:
map
[
string
]
string
{
"name"
:
spec
.
Name
},
},
ObjectMeta
:
objectMeta
,
Spec
:
api
.
PodSpec
{
Containers
:
[]
api
.
Container
{{
Name
:
spec
.
Name
,
...
...
@@ -72,12 +86,10 @@ func DeployApp(spec *AppDeploymentSpec, client *client.Client) error {
}
replicaSet
:=
&
api
.
ReplicationController
{
ObjectMeta
:
api
.
ObjectMeta
{
Name
:
spec
.
Name
,
},
ObjectMeta
:
objectMeta
,
Spec
:
api
.
ReplicationControllerSpec
{
Replicas
:
spec
.
Replicas
,
Selector
:
map
[
string
]
string
{
"name"
:
spec
.
Name
}
,
Selector
:
labels
,
Template
:
podTemplate
,
},
}
...
...
@@ -91,12 +103,9 @@ func DeployApp(spec *AppDeploymentSpec, client *client.Client) error {
if
len
(
spec
.
PortMappings
)
>
0
{
service
:=
&
api
.
Service
{
ObjectMeta
:
api
.
ObjectMeta
{
Name
:
spec
.
Name
,
Labels
:
map
[
string
]
string
{
"name"
:
spec
.
Name
},
},
ObjectMeta
:
objectMeta
,
Spec
:
api
.
ServiceSpec
{
Selector
:
map
[
string
]
string
{
"name"
:
spec
.
Name
}
,
Selector
:
labels
,
},
}
...
...
src/app/backend/namespaces.go
浏览文件 @
d6c3b563
...
...
@@ -28,7 +28,7 @@ type NamespaceSpec struct {
}
// List of Namespaces in the cluster.
type
Namespace
s
List
struct
{
type
NamespaceList
struct
{
// Unordered list of Namespaces.
Namespaces
[]
string
`json:"namespaces"`
}
...
...
@@ -47,14 +47,14 @@ func CreateNamespace(spec *NamespaceSpec, client *client.Client) error {
}
// Returns a list of all namespaces in the cluster.
func
GetNamespaceList
(
client
*
client
.
Client
)
(
*
Namespace
s
List
,
error
)
{
func
GetNamespaceList
(
client
*
client
.
Client
)
(
*
NamespaceList
,
error
)
{
list
,
err
:=
client
.
Namespaces
()
.
List
(
labels
.
Everything
(),
fields
.
Everything
())
if
err
!=
nil
{
return
nil
,
err
}
namespaceList
:=
&
Namespace
s
List
{}
namespaceList
:=
&
NamespaceList
{}
for
_
,
element
:=
range
list
.
Items
{
namespaceList
.
Namespaces
=
append
(
namespaceList
.
Namespaces
,
element
.
ObjectMeta
.
Name
)
...
...
src/app/backend/replicasetlist.go
浏览文件 @
d6c3b563
...
...
@@ -20,6 +20,8 @@ import (
client
"k8s.io/kubernetes/pkg/client/unversioned"
"k8s.io/kubernetes/pkg/fields"
"k8s.io/kubernetes/pkg/labels"
"strconv"
"strings"
)
// List of Replica Sets in the cluster.
...
...
@@ -56,47 +58,131 @@ type ReplicaSet struct {
CreationTime
unversioned
.
Time
`json:"creationTime"`
// Internal endpoints of all Kubernetes services have the same label selector as this Replica Set.
// Endpoint is DNS name merged with ports.
InternalEndpoints
[]
string
`json:"internalEndpoints"`
// External endpoints of all Kubernetes services have the same label selector as this Replica Set.
// Endpoint is external IP address name merged with ports.
ExternalEndpoints
[]
string
`json:"externalEndpoints"`
}
// Returns a list of all Replica Sets in the cluster.
func
GetReplicaSetList
(
client
*
client
.
Client
)
(
*
ReplicaSetList
,
error
)
{
list
,
err
:=
client
.
ReplicationControllers
(
api
.
NamespaceAll
)
.
replicaSets
,
err
:=
client
.
ReplicationControllers
(
api
.
NamespaceAll
)
.
List
(
labels
.
Everything
(),
fields
.
Everything
())
if
err
!=
nil
{
return
nil
,
err
}
services
,
err
:=
client
.
Services
(
api
.
NamespaceAll
)
.
List
(
labels
.
Everything
(),
fields
.
Everything
())
if
err
!=
nil
{
return
nil
,
err
}
return
getReplicaSetList
(
replicaSets
.
Items
,
services
.
Items
),
nil
}
// Returns a list of all Replica Set model objects in the cluster, based on all Kubernetes
// Replica Set and Service API objects.
// The function processes all Replica Sets API objects and finds matching Services for them.
func
getReplicaSetList
(
replicaSets
[]
api
.
ReplicationController
,
services
[]
api
.
Service
)
*
ReplicaSetList
{
replicaSetList
:=
&
ReplicaSetList
{}
for
_
,
replicaSet
:=
range
list
.
Item
s
{
for
_
,
replicaSet
:=
range
replicaSet
s
{
var
containerImages
[]
string
for
_
,
container
:=
range
replicaSet
.
Spec
.
Template
.
Spec
.
Containers
{
containerImages
=
append
(
containerImages
,
container
.
Image
)
}
matchingServices
:=
getMatchingServices
(
services
,
&
replicaSet
)
var
internalEndpoints
[]
string
var
externalEndpoints
[]
string
for
_
,
service
:=
range
matchingServices
{
internalEndpoints
=
append
(
internalEndpoints
,
getInternalEndpoint
(
service
.
Name
,
service
.
Namespace
,
service
.
Spec
.
Ports
))
for
_
,
externalIp
:=
range
service
.
Status
.
LoadBalancer
.
Ingress
{
externalEndpoints
=
append
(
externalEndpoints
,
getExternalEndpoint
(
externalIp
.
Hostname
,
service
.
Spec
.
Ports
))
}
}
replicaSetList
.
ReplicaSets
=
append
(
replicaSetList
.
ReplicaSets
,
ReplicaSet
{
Name
:
replicaSet
.
ObjectMeta
.
Name
,
Namespace
:
replicaSet
.
ObjectMeta
.
Namespace
,
// TODO(bryk): This field contains test value. Implement it.
Description
:
"Lorem ipsum dolor sit amet, consectetur adipiscing elit. "
+
"Nulla metus nibh, iaculis a consectetur vitae, imperdiet pellentesque turpis."
,
Labels
:
replicaSet
.
ObjectMeta
.
Labels
,
PodsRunning
:
replicaSet
.
Status
.
Replicas
,
PodsPending
:
replicaSet
.
Spec
.
Replicas
-
replicaSet
.
Status
.
Replicas
,
ContainerImages
:
containerImages
,
CreationTime
:
replicaSet
.
ObjectMeta
.
CreationTimestamp
,
// TODO(bryk): This field contains test value. Implement it.
InternalEndpoints
:
[]
string
{
"webapp"
},
// TODO(bryk): This field contains test value. Implement it.
ExternalEndpoints
:
[]
string
{
"81.76.02.198:80"
},
Name
:
replicaSet
.
ObjectMeta
.
Name
,
Namespace
:
replicaSet
.
ObjectMeta
.
Namespace
,
Description
:
replicaSet
.
Annotations
[
DescriptionAnnotationKey
],
Labels
:
replicaSet
.
ObjectMeta
.
Labels
,
PodsRunning
:
replicaSet
.
Status
.
Replicas
,
PodsPending
:
replicaSet
.
Spec
.
Replicas
-
replicaSet
.
Status
.
Replicas
,
ContainerImages
:
containerImages
,
CreationTime
:
replicaSet
.
ObjectMeta
.
CreationTimestamp
,
InternalEndpoints
:
internalEndpoints
,
ExternalEndpoints
:
externalEndpoints
,
})
}
return
replicaSetList
,
nil
return
replicaSetList
}
// Returns internal endpoint name for the given service properties, e.g.,
// "my-service.namespace 80/TCP" or "my-service 53/TCP,53/UDP".
func
getInternalEndpoint
(
serviceName
string
,
namespace
string
,
ports
[]
api
.
ServicePort
)
string
{
name
:=
serviceName
if
namespace
!=
api
.
NamespaceDefault
{
name
=
name
+
"."
+
namespace
}
return
name
+
getServicePortsName
(
ports
)
}
// Returns external endpoint name for the given service properties.
func
getExternalEndpoint
(
serviceIp
string
,
ports
[]
api
.
ServicePort
)
string
{
return
serviceIp
+
getServicePortsName
(
ports
)
}
// Gets human readable name for the given service ports list.
func
getServicePortsName
(
ports
[]
api
.
ServicePort
)
string
{
var
portsString
[]
string
for
_
,
port
:=
range
ports
{
portsString
=
append
(
portsString
,
strconv
.
Itoa
(
port
.
Port
)
+
"/"
+
string
(
port
.
Protocol
))
}
if
len
(
portsString
)
>
0
{
return
" "
+
strings
.
Join
(
portsString
,
","
)
}
else
{
return
""
}
}
// 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
{
var
matchingServices
[]
api
.
Service
for
_
,
service
:=
range
services
{
if
isServiceMatchingReplicaSet
(
service
.
Spec
.
Selector
,
replicaSet
.
Spec
.
Selector
)
{
matchingServices
=
append
(
matchingServices
,
service
)
}
}
return
matchingServices
}
// Returns true when a Service with the given selector targets the same Pods (or subset) that
// a Replica Set with the given selector.
func
isServiceMatchingReplicaSet
(
serviceSelector
map
[
string
]
string
,
replicaSetSpecSelector
map
[
string
]
string
)
bool
{
// If service has no selectors, then assume it targets different Pods.
if
len
(
serviceSelector
)
==
0
{
return
false
}
for
label
,
value
:=
range
serviceSelector
{
if
rsValue
,
ok
:=
replicaSetSpecSelector
[
label
];
!
ok
||
rsValue
!=
value
{
return
false
}
}
return
true
}
src/app/externs/backendapi.js
浏览文件 @
d6c3b563
...
...
@@ -38,6 +38,7 @@ backendApi.PortMapping;
* containerImage: string,
* isExternal: boolean,
* name: string,
* description: string,
* portMappings: !Array<!backendApi.PortMapping>,
* replicas: number,
* namespace: string
...
...
src/app/frontend/deploy/deploy.html
浏览文件 @
d6c3b563
...
...
@@ -18,7 +18,7 @@ limitations under the License.
<md-whiteframe
class=
"kd-deploy-whiteframe md-whiteframe-5dp"
flex
flex-gt-md
>
<h3
class=
"md-headline"
>
Deploy a Containerized App
</h3>
<form
ng-submit=
"ctrl.deploy()"
>
<md-input-container
class=
"md-block"
>
<md-input-container>
<label>
App name
</label>
<input
ng-model=
"ctrl.name"
required
>
</md-input-container>
...
...
@@ -30,24 +30,24 @@ limitations under the License.
Upload a YAML or JSON file
</md-radio-button>
</md-radio-group>
<md-input-container
class=
"md-block"
>
<md-input-container>
<label>
Container image
</label>
<input
ng-model=
"ctrl.containerImage"
required
>
</md-input-container>
<md-input-container
class=
"md-block"
>
<md-input-container>
<label>
Number of pods
</label>
<input
ng-model=
"ctrl.replicas"
type=
"number"
required
min=
"1"
>
</md-input-container>
<div
layout=
"row"
ng-repeat=
"portMapping in ctrl.portMappings"
>
<md-input-container
class=
"md-block"
>
<md-input-container
flex
>
<label>
Port
</label>
<input
ng-model=
"portMapping.port"
type=
"number"
min=
"0"
>
</md-input-container>
<md-input-container
class=
"md-block"
>
<md-input-container
flex
>
<label>
Target port
</label>
<input
ng-model=
"portMapping.targetPort"
type=
"number"
min=
"0"
>
</md-input-container>
<md-input-container
class=
"md-block
"
>
<md-input-container
flex=
"none
"
>
<label>
Protocol
</label>
<md-select
ng-model=
"portMapping.protocol"
required
>
<md-option
ng-repeat=
"protocol in ctrl.protocols"
ng-value=
"protocol"
>
...
...
@@ -56,7 +56,7 @@ limitations under the License.
</md-select>
</md-input-container>
</div>
<md-input-container
class=
"md-block"
>
<md-input-container>
<label>
Namespace
</label>
<md-select
ng-model=
"ctrl.namespace"
required
>
<md-option
ng-repeat=
"namespace in ctrl.namespaces"
ng-value=
"namespace"
>
...
...
@@ -70,6 +70,10 @@ limitations under the License.
<md-switch
ng-model=
"ctrl.isExternal"
class=
"md-primary"
>
Expose service externally
</md-switch>
<md-input-container>
<label>
Description (optional)
</label>
<textarea
ng-model=
"ctrl.description"
></textarea>
</md-input-container>
<md-button
class=
"md-raised md-primary"
type=
"submit"
ng-disabled=
"ctrl.isDeployDisabled()"
>
Deploy
</md-button>
...
...
src/app/frontend/deploy/deploy_controller.js
浏览文件 @
d6c3b563
...
...
@@ -40,6 +40,9 @@ export default class DeployController {
/** @export {number} */
this
.
replicas
=
1
;
/** @export {string} */
this
.
description
=
''
;
/**
* List of supported protocols.
* TODO(bryk): Do not hardcode the here, move to backend.
...
...
@@ -94,6 +97,7 @@ export default class DeployController {
containerImage
:
this
.
containerImage
,
isExternal
:
this
.
isExternal
,
name
:
this
.
name
,
description
:
this
.
description
,
portMappings
:
this
.
portMappings
.
filter
(
this
.
isPortMappingEmpty_
),
replicas
:
this
.
replicas
,
namespace
:
this
.
namespace
,
...
...
src/app/frontend/replicasetlist/replicasetlist.html
浏览文件 @
d6c3b563
...
...
@@ -15,17 +15,17 @@ limitations under the License.
-->
<div
layout=
"row"
layout-wrap
layout-margin
layout-align=
"center center"
>
<md-card
ng-repeat=
"replicaSet in ctrl.replicaSets"
>
<md-card
ng-repeat=
"replicaSet in
::
ctrl.replicaSets"
>
<md-card-content
class=
"kd-replicaset-card"
>
<div
layout=
"row"
layout-align=
"space-between center"
>
<div
flex
layout=
"column"
>
<a
ng-href=
"{{ctrl.getReplicaSetDetailHref(replicaSet)}}"
flex
>
{{replicaSet.name}}
<a
ng-href=
"{{
::
ctrl.getReplicaSetDetailHref(replicaSet)}}"
flex
>
{{
::
replicaSet.name}}
</a>
<div
flex
class=
"md-caption"
>
<span
ng-repeat=
"(label, value) in replicaSet.labels"
<span
ng-repeat=
"(label, value) in
::
replicaSet.labels"
class=
"kd-replicaset-card-label"
>
{{
label}}:{{
value}}
{{
::label}}:{{::
value}}
</span>
</div>
</div>
...
...
@@ -36,50 +36,56 @@ limitations under the License.
<div
class=
"md-caption"
>
<div
layout=
"row"
>
<span
flex=
"60"
>
{{
replicaSet.podsRunning}} pods running, {{
replicaSet.podsPending}} pending
{{
::replicaSet.podsRunning}} pods running, {{::
replicaSet.podsPending}} pending
</span>
<a
flex=
"40"
href=
"#"
class=
"kd-replicaset-card-logs"
>
Logs
</a>
</div>
<hr
class=
"kd-replicaset-card-divider"
></hr>
<div
layout=
"row"
layout-wrap
>
<div
ng-if=
"replicaSet.description"
flex=
"100"
layout=
"column"
<div
ng-if=
"
::
replicaSet.description"
flex=
"100"
layout=
"column"
class=
"kd-replicaset-card-section"
>
<span
flex
>
Description
</span>
<div
flex
>
{{replicaSet.description}}
{{
::
replicaSet.description}}
</div>
</div>
<div
flex=
"60"
layout=
"column"
class=
"kd-replicaset-card-section"
>
<span
flex
>
Image
</span>
<div
flex
>
<div
ng-repeat=
"image in
replicaSet.containerImages
"
<div
ng-repeat=
"image in
::replicaSet.containerImages track by $index
"
class=
"kd-replicaset-card-section-image"
>
{{image}}
{{
::
image}}
</div>
</div>
</div>
<div
flex=
"40"
layout=
"column"
class=
"kd-replicaset-card-section"
>
<span
flex=
"initial"
>
Creation time
</span>
<span
flex
>
{{replicaSet.creationTime}}
</span>
<span
flex
>
{{
::
replicaSet.creationTime}}
</span>
</div>
<div
flex=
"60"
layout=
"column"
class=
"kd-replicaset-card-section"
>
<span
flex=
"initial"
>
Internal Endpoint
</span>
<div
flex
>
<span
ng-repeat=
"endpoint in replicaSet.internalEndpoints"
>
{{endpoint}}
</span>
<div
ng-repeat=
"endpoint in ::replicaSet.internalEndpoints track by $index"
>
{{::endpoint}}
</div>
<div
ng-if=
"::!replicaSet.internalEndpoints.length"
>
none
</div>
</div>
</div>
<div
flex=
"40"
layout=
"column"
class=
"kd-replicaset-card-section"
>
<span
flex=
"initial"
>
External Endpoint
</span>
<div
flex
>
<span
ng-repeat=
"endpoint in replicaSet.externalEndpoints"
>
{{endpoint}}
</span>
<div
ng-repeat=
"endpoint in ::replicaSet.externalEndpoints track by $index"
>
<a
ng-href=
"http://{{::endpoint}}"
target=
"_blank"
>
{{::endpoint}}
</a>
</div>
<div
ng-if=
"::!replicaSet.externalEndpoints.length"
>
none
</div>
</div>
</div>
</div>
...
...
src/test/backend/apiserverclient_test.go
浏览文件 @
d6c3b563
...
...
@@ -15,7 +15,6 @@
package
main
import
(
backend
"app/backend"
client
"k8s.io/kubernetes/pkg/client/unversioned"
"testing"
)
...
...
@@ -34,14 +33,14 @@ func (FakeClientFactory) NewInCluster() (*client.Client, error) {
}
func
TestCreateApiserverClient_inCluster
(
t
*
testing
.
T
)
{
client
,
_
:=
backend
.
CreateApiserverClient
(
""
,
new
(
FakeClientFactory
))
client
,
_
:=
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
))
client
,
_
:=
CreateApiserverClient
(
"http://foo:bar"
,
new
(
FakeClientFactory
))
if
client
!=
fakeRemoteClient
{
t
.
Fatal
(
"Expected remote client to be created"
)
}
...
...
src/test/backend/replicasetlist_test.go
0 → 100644
浏览文件 @
d6c3b563
// 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
main
import
(
"testing"
)
func
TestFoo
(
t
*
testing
.
T
)
{
// TODO(bryk): Write tests here.
isServiceMatchingReplicaSet
(
nil
,
nil
)
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录