Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
凌波微步_大先生
dashboard
提交
eccb746a
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,发现更多精彩内容 >>
提交
eccb746a
编写于
11月 30, 2015
作者:
P
Piotr Bryk
浏览文件
操作
浏览文件
下载
差异文件
Merge pull request #100 from maciaszczykm/deploy-namespaces
Implemented create new namespace dialog
上级
d408561a
c7bf42bd
变更
9
隐藏空白更改
内联
并排
Showing
9 changed file
with
268 addition
and
36 deletion
+268
-36
src/app/backend/apihandler.go
src/app/backend/apihandler.go
+35
-13
src/app/backend/deploy.go
src/app/backend/deploy.go
+17
-17
src/app/backend/namespaces.go
src/app/backend/namespaces.go
+20
-0
src/app/externs/backendapi.js
src/app/externs/backendapi.js
+8
-1
src/app/frontend/deploy/createnamespace.html
src/app/frontend/deploy/createnamespace.html
+33
-0
src/app/frontend/deploy/createnamespace_controller.js
src/app/frontend/deploy/createnamespace_controller.js
+81
-0
src/app/frontend/deploy/createnamespace_dialog.js
src/app/frontend/deploy/createnamespace_dialog.js
+36
-0
src/app/frontend/deploy/deploy.html
src/app/frontend/deploy/deploy.html
+3
-0
src/app/frontend/deploy/deploy_controller.js
src/app/frontend/deploy/deploy_controller.js
+35
-5
未找到文件。
src/app/backend/apihandler.go
浏览文件 @
eccb746a
...
...
@@ -33,8 +33,8 @@ func CreateHttpApiHandler(client *client.Client) http.Handler {
deployWs
.
Route
(
deployWs
.
POST
(
""
)
.
To
(
apiHandler
.
handleDeploy
)
.
Reads
(
AppDeployment
{})
.
Writes
(
AppDeployment
{}))
Reads
(
AppDeployment
Spec
{})
.
Writes
(
AppDeployment
Spec
{}))
wsContainer
.
Add
(
deployWs
)
replicaSetWs
:=
new
(
restful
.
WebService
)
...
...
@@ -50,14 +50,20 @@ func CreateHttpApiHandler(client *client.Client) http.Handler {
Writes
(
ReplicaSetDetail
{}))
wsContainer
.
Add
(
replicaSetWs
)
namespaceListWs
:=
new
(
restful
.
WebService
)
namespaceListWs
.
Path
(
"/api/namespaces"
)
.
namespacesWs
:=
new
(
restful
.
WebService
)
namespacesWs
.
Path
(
"/api/namespaces"
)
.
Consumes
(
restful
.
MIME_JSON
)
.
Produces
(
restful
.
MIME_JSON
)
namespaceListWs
.
Route
(
namespaceListWs
.
GET
(
""
)
.
To
(
apiHandler
.
handleGetNamespaceList
)
.
namespacesWs
.
Route
(
namespacesWs
.
POST
(
""
)
.
To
(
apiHandler
.
handleCreateNamespace
)
.
Reads
(
NamespaceSpec
{})
.
Writes
(
NamespaceSpec
{}))
namespacesWs
.
Route
(
namespacesWs
.
GET
(
""
)
.
To
(
apiHandler
.
handleGetNamespaces
)
.
Writes
(
NamespacesList
{}))
wsContainer
.
Add
(
namespace
List
Ws
)
wsContainer
.
Add
(
namespace
s
Ws
)
logsWs
:=
new
(
restful
.
WebService
)
logsWs
.
Path
(
"/api/logs"
)
.
...
...
@@ -77,17 +83,17 @@ type ApiHandler struct {
// Handles deploy API call.
func
(
apiHandler
*
ApiHandler
)
handleDeploy
(
request
*
restful
.
Request
,
response
*
restful
.
Response
)
{
cfg
:=
new
(
AppDeployment
)
if
err
:=
request
.
ReadEntity
(
cfg
);
err
!=
nil
{
appDeploymentSpec
:=
new
(
AppDeploymentSpec
)
if
err
:=
request
.
ReadEntity
(
appDeploymentSpec
);
err
!=
nil
{
handleInternalError
(
response
,
err
)
return
}
if
err
:=
DeployApp
(
cfg
,
apiHandler
.
client
);
err
!=
nil
{
if
err
:=
DeployApp
(
appDeploymentSpec
,
apiHandler
.
client
);
err
!=
nil
{
handleInternalError
(
response
,
err
)
return
}
response
.
WriteHeaderAndEntity
(
http
.
StatusCreated
,
cfg
)
response
.
WriteHeaderAndEntity
(
http
.
StatusCreated
,
appDeploymentSpec
)
}
// Handles get Replica Set list API call.
...
...
@@ -118,8 +124,24 @@ func (apiHandler *ApiHandler) handleGetReplicaSetDetail(
response
.
WriteHeaderAndEntity
(
http
.
StatusCreated
,
result
)
}
// Handles namespace creation API call.
func
(
apiHandler
*
ApiHandler
)
handleCreateNamespace
(
request
*
restful
.
Request
,
response
*
restful
.
Response
)
{
namespaceSpec
:=
new
(
NamespaceSpec
)
if
err
:=
request
.
ReadEntity
(
namespaceSpec
);
err
!=
nil
{
handleInternalError
(
response
,
err
)
return
}
if
err
:=
CreateNamespace
(
namespaceSpec
,
apiHandler
.
client
);
err
!=
nil
{
handleInternalError
(
response
,
err
)
return
}
response
.
WriteHeaderAndEntity
(
http
.
StatusCreated
,
namespaceSpec
)
}
// Handles get namespace list API call.
func
(
apiHandler
*
ApiHandler
)
handleGetNamespace
List
(
func
(
apiHandler
*
ApiHandler
)
handleGetNamespace
s
(
request
*
restful
.
Request
,
response
*
restful
.
Response
)
{
result
,
err
:=
GetNamespaceList
(
apiHandler
.
client
)
...
...
src/app/backend/deploy.go
浏览文件 @
eccb746a
...
...
@@ -20,8 +20,8 @@ import (
"k8s.io/kubernetes/pkg/util"
)
//
Configur
ation for an app deployment.
type
AppDeployment
struct
{
//
Specific
ation for an app deployment.
type
AppDeployment
Spec
struct
{
// Name of the application.
Name
string
`json:"name"`
...
...
@@ -58,55 +58,55 @@ type PortMapping struct {
// App deployment consists of a replication controller and an optional service. Both of them share
// common labels.
// TODO(bryk): Write tests for this function.
func
DeployApp
(
deployment
*
AppDeployment
,
client
*
client
.
Client
)
error
{
func
DeployApp
(
spec
*
AppDeploymentSpec
,
client
*
client
.
Client
)
error
{
podTemplate
:=
&
api
.
PodTemplateSpec
{
ObjectMeta
:
api
.
ObjectMeta
{
Labels
:
map
[
string
]
string
{
"name"
:
deployment
.
Name
},
Labels
:
map
[
string
]
string
{
"name"
:
spec
.
Name
},
},
Spec
:
api
.
PodSpec
{
Containers
:
[]
api
.
Container
{{
Name
:
deployment
.
Name
,
Image
:
deployment
.
ContainerImage
,
Name
:
spec
.
Name
,
Image
:
spec
.
ContainerImage
,
}},
},
}
replicaSet
:=
&
api
.
ReplicationController
{
ObjectMeta
:
api
.
ObjectMeta
{
Name
:
deployment
.
Name
,
Name
:
spec
.
Name
,
},
Spec
:
api
.
ReplicationControllerSpec
{
Replicas
:
deployment
.
Replicas
,
Selector
:
map
[
string
]
string
{
"name"
:
deployment
.
Name
},
Replicas
:
spec
.
Replicas
,
Selector
:
map
[
string
]
string
{
"name"
:
spec
.
Name
},
Template
:
podTemplate
,
},
}
_
,
err
:=
client
.
ReplicationControllers
(
deployment
.
Namespace
)
.
Create
(
replicaSet
)
_
,
err
:=
client
.
ReplicationControllers
(
spec
.
Namespace
)
.
Create
(
replicaSet
)
if
err
!=
nil
{
// TODO(bryk): Roll back created resources in case of error.
return
err
}
if
len
(
deployment
.
PortMappings
)
>
0
{
if
len
(
spec
.
PortMappings
)
>
0
{
service
:=
&
api
.
Service
{
ObjectMeta
:
api
.
ObjectMeta
{
Name
:
deployment
.
Name
,
Labels
:
map
[
string
]
string
{
"name"
:
deployment
.
Name
},
Name
:
spec
.
Name
,
Labels
:
map
[
string
]
string
{
"name"
:
spec
.
Name
},
},
Spec
:
api
.
ServiceSpec
{
Selector
:
map
[
string
]
string
{
"name"
:
deployment
.
Name
},
Selector
:
map
[
string
]
string
{
"name"
:
spec
.
Name
},
},
}
if
deployment
.
IsExternal
{
if
spec
.
IsExternal
{
service
.
Spec
.
Type
=
api
.
ServiceTypeLoadBalancer
}
else
{
service
.
Spec
.
Type
=
api
.
ServiceTypeNodePort
}
for
_
,
portMapping
:=
range
deployment
.
PortMappings
{
for
_
,
portMapping
:=
range
spec
.
PortMappings
{
servicePort
:=
api
.
ServicePort
{
Protocol
:
portMapping
.
Protocol
,
...
...
@@ -119,7 +119,7 @@ func DeployApp(deployment *AppDeployment, client *client.Client) error {
service
.
Spec
.
Ports
=
append
(
service
.
Spec
.
Ports
,
servicePort
)
}
_
,
err
=
client
.
Services
(
deployment
.
Namespace
)
.
Create
(
service
)
_
,
err
=
client
.
Services
(
spec
.
Namespace
)
.
Create
(
service
)
// TODO(bryk): Roll back created resources in case of error.
...
...
src/app/backend/namespace
list
.go
→
src/app/backend/namespace
s
.go
浏览文件 @
eccb746a
...
...
@@ -15,17 +15,37 @@
package
main
import
(
api
"k8s.io/kubernetes/pkg/api"
client
"k8s.io/kubernetes/pkg/client/unversioned"
"k8s.io/kubernetes/pkg/fields"
"k8s.io/kubernetes/pkg/labels"
)
// Specification of namespace to be created.
type
NamespaceSpec
struct
{
// Name of the namespace.
Name
string
`json:"name"`
}
// List of Namespaces in the cluster.
type
NamespacesList
struct
{
// Unordered list of Namespaces.
Namespaces
[]
string
`json:"namespaces"`
}
// Creates namespace based on given specification.
func
CreateNamespace
(
spec
*
NamespaceSpec
,
client
*
client
.
Client
)
error
{
namespace
:=
&
api
.
Namespace
{
ObjectMeta
:
api
.
ObjectMeta
{
Name
:
spec
.
Name
,
},
}
_
,
err
:=
client
.
Namespaces
()
.
Create
(
namespace
)
return
err
}
// Returns a list of all namespaces in the cluster.
func
GetNamespaceList
(
client
*
client
.
Client
)
(
*
NamespacesList
,
error
)
{
list
,
err
:=
client
.
Namespaces
()
.
List
(
labels
.
Everything
(),
fields
.
Everything
())
...
...
src/app/externs/backendapi.js
浏览文件 @
eccb746a
...
...
@@ -43,7 +43,7 @@ backendApi.PortMapping;
* namespace: string
* }}
*/
backendApi
.
AppDeployment
;
backendApi
.
AppDeployment
Spec
;
/**
* @typedef {{
...
...
@@ -92,6 +92,13 @@ backendApi.ReplicaSetDetail;
*/
backendApi
.
ReplicaSetPod
;
/**
* @typedef {{
* name: string
* }}
*/
backendApi
.
NamespaceSpec
;
/**
* @typedef {{
* namespaces: !Array<string>
...
...
src/app/frontend/deploy/createnamespace.html
0 → 100644
浏览文件 @
eccb746a
<!--
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.
-->
<md-dialog
aria-label=
"Create a new namespace"
layout=
"column"
layout-padding
>
<md-content
layout-padding
>
<h4
class=
"md-title"
>
Create a new namespace
</h4>
<p>
The new namespace will be added to the cluster.
</p>
<!-- TODO(maciaszczykm): Missing detailed cluster info and learn more link. -->
<form
id=
"namespaceForm"
ng-submit=
"ctrl.createNamespace()"
>
<md-input-container
class=
"md-block"
>
<label>
Namespace name
</label>
<input
ng-model=
"ctrl.namespace"
required
>
</md-input-container>
<div
class=
"md-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>
</form>
</md-content>
</md-dialog>
src/app/frontend/deploy/createnamespace_controller.js
0 → 100644
浏览文件 @
eccb746a
// 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.
/**
* Namespace creation dialog controller.
*
* @final
*/
export
default
class
NamespaceDialogController
{
/**
* @param {!md.$dialog} $mdDialog
* @param {!angular.$log} $log
* @param {!angular.$resource} $resource
* @param {!Array<string>} namespaces
* @ngInject
*/
constructor
(
$mdDialog
,
$log
,
$resource
,
namespaces
)
{
/** @private {!md.$dialog} */
this
.
mdDialog_
=
$mdDialog
;
/** @private {!angular.$log} */
this
.
log_
=
$log
;
/** @private {!angular.$resource} */
this
.
resource_
=
$resource
;
/**
* List of available namespaces.
* @export {!Array<string>}
*/
this
.
namespaces
=
namespaces
;
/** @export {string} */
this
.
namespace
=
''
;
}
/**
* Returns true if new namespace name hasn't been filled by the user, i.e, is empty.
* @return {boolean}
*/
isDisabled
()
{
return
!
this
.
namespace
||
/^
\s
*$/
.
test
(
!
this
.
namespace
)
||
this
.
namespaces
.
indexOf
(
this
.
namespace
)
>=
0
;
}
/** Cancels the new namespace form. */
cancel
()
{
this
.
mdDialog_
.
cancel
();
}
/**
* Creates new namespace based on the state of the controller.
*/
createNamespace
()
{
/** @type {!backendApi.NamespaceSpec} */
let
namespaceSpec
=
{
name
:
this
.
namespace
};
/** @type {!angular.Resource<!backendApi.NamespaceSpec>} */
let
resource
=
this
.
resource_
(
'
/api/namespaces
'
);
resource
.
save
(
namespaceSpec
,
(
savedConfig
)
=>
{
this
.
log_
.
info
(
'
Successfully created namespace:
'
,
savedConfig
);
this
.
mdDialog_
.
hide
(
this
.
namespace
);
},
(
err
)
=>
{
this
.
log_
.
info
(
'
Error creating namespace:
'
,
err
);
this
.
mdDialog_
.
hide
();
});
}
}
src/app/frontend/deploy/createnamespace_dialog.js
0 → 100644
浏览文件 @
eccb746a
// 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.
import
NamespaceDialogController
from
'
deploy/createnamespace_controller
'
;
/**
* Displays new namespace creation dialog.
*
* @param {!md.$dialog} mdDialog
* @param {!angular.Scope.Event} event
* @param {!Array<string>} namespaces
* @return {!angular.$q.Promise}
*/
export
default
function
showNamespaceDialog
(
mdDialog
,
event
,
namespaces
)
{
return
mdDialog
.
show
({
controller
:
NamespaceDialogController
,
controllerAs
:
'
ctrl
'
,
clickOutsideToClose
:
true
,
targetEvent
:
event
,
templateUrl
:
'
/deploy/createnamespace.html
'
,
locals
:
{
namespaces
:
namespaces
,
},
});
}
src/app/frontend/deploy/deploy.html
浏览文件 @
eccb746a
...
...
@@ -62,6 +62,9 @@ limitations under the License.
<md-option
ng-repeat=
"namespace in ctrl.namespaces"
ng-value=
"namespace"
>
{{namespace}}
</md-option>
<md-option
ng-click=
"ctrl.handleNamespaceDialog($event)"
>
Create a new namespace...
</md-option>
</md-select>
</md-input-container>
<md-switch
ng-model=
"ctrl.isExternal"
class=
"md-primary"
>
...
...
src/app/frontend/deploy/deploy_controller.js
浏览文件 @
eccb746a
...
...
@@ -14,6 +14,7 @@
import
{
stateName
as
zerostate
}
from
'
zerostate/zerostate_state
'
;
import
{
stateName
as
replicasetliststate
}
from
'
replicasetlist/replicasetlist_state
'
;
import
showNamespaceDialog
from
'
deploy/createnamespace_dialog
'
;
/**
* Controller for the deploy view.
...
...
@@ -25,10 +26,11 @@ export default class DeployController {
* @param {!angular.$resource} $resource
* @param {!angular.$log} $log
* @param {!ui.router.$state} $state
* @param {!md.$dialog} $mdDialog
* @param {!backendApi.NamespaceList} namespaces
* @ngInject
*/
constructor
(
$resource
,
$log
,
$state
,
namespaces
)
{
constructor
(
$resource
,
$log
,
$state
,
$mdDialog
,
namespaces
)
{
/** @export {string} */
this
.
name
=
''
;
...
...
@@ -72,6 +74,9 @@ export default class DeployController {
/** @private {!ui.router.$state} */
this
.
state_
=
$state
;
/** @private {!md.$dialog} */
this
.
mdDialog_
=
$mdDialog
;
/** @private {boolean} */
this
.
isDeployInProgress_
=
false
;
}
...
...
@@ -84,8 +89,8 @@ export default class DeployController {
deploy
()
{
// TODO(bryk): Validate input data before sending to the server.
/** @type {!backendApi.AppDeployment} */
let
deployAppConfig
=
{
/** @type {!backendApi.AppDeployment
Spec
} */
let
appDeploymentSpec
=
{
containerImage
:
this
.
containerImage
,
isExternal
:
this
.
isExternal
,
name
:
this
.
name
,
...
...
@@ -94,12 +99,12 @@ export default class DeployController {
namespace
:
this
.
namespace
,
};
/** @type {!angular.Resource<!backendApi.AppDeployment>} */
/** @type {!angular.Resource<!backendApi.AppDeployment
Spec
>} */
let
resource
=
this
.
resource_
(
'
/api/appdeployments
'
);
this
.
isDeployInProgress_
=
true
;
resource
.
save
(
deployAppConfig
,
appDeploymentSpec
,
(
savedConfig
)
=>
{
this
.
isDeployInProgress_
=
false
;
this
.
log_
.
info
(
'
Successfully deployed application:
'
,
savedConfig
);
...
...
@@ -111,6 +116,31 @@ export default class DeployController {
});
}
/**
* Displays new namespace creation dialog.
*
* @param {!angular.Scope.Event} event
*/
handleNamespaceDialog
(
event
)
{
showNamespaceDialog
(
this
.
mdDialog_
,
event
,
this
.
namespaces
)
.
then
(
/**
* Handles namespace dialog result. If namespace was created successfully then it
* will be selected, otherwise first namespace will be selected.
*
* @param {string|undefined} answer
*/
(
answer
)
=>
{
if
(
answer
)
{
this
.
namespace
=
answer
;
this
.
namespaces
=
this
.
namespaces
.
concat
(
answer
);
}
else
{
this
.
namespace
=
this
.
namespaces
[
0
];
}
},
()
=>
{
this
.
namespace
=
this
.
namespaces
[
0
];
});
}
/**
* Returns true when the deploy action should be enabled.
* @return {boolean}
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录