Skip to content

Commit 1da4b1c

Browse files
Marcin MaciaszczykMarcin Maciaszczyk
authored andcommitted
Implemented existing namespaces handling in deploy form
1 parent ef0ce26 commit 1da4b1c

File tree

8 files changed

+144
-7
lines changed

8 files changed

+144
-7
lines changed

src/app/backend/apihandler.go

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,15 @@ func CreateHttpApiHandler(client *client.Client) http.Handler {
4646
Writes(ReplicaSetList{}))
4747
wsContainer.Add(replicaSetListWs)
4848

49+
namespaceListWs := new(restful.WebService)
50+
namespaceListWs.Path("/api/namespace").
51+
Produces(restful.MIME_JSON)
52+
namespaceListWs.Route(
53+
namespaceListWs.GET("").
54+
To(apiHandler.handleGetNamespaceList).
55+
Writes(NamespacesList{}))
56+
wsContainer.Add(namespaceListWs)
57+
4958
return wsContainer
5059
}
5160

@@ -81,6 +90,19 @@ func (apiHandler *ApiHandler) handleGetReplicaSetList(
8190
response.WriteHeaderAndEntity(http.StatusCreated, result)
8291
}
8392

93+
// Handles get namespace list API call.
94+
func (apiHandler *ApiHandler) handleGetNamespaceList(
95+
request *restful.Request, response *restful.Response) {
96+
97+
result, err := GetNamespaceList(apiHandler.client)
98+
if err != nil {
99+
handleInternalError(response, err)
100+
return
101+
}
102+
103+
response.WriteHeaderAndEntity(http.StatusCreated, result)
104+
}
105+
84106
// Handler that writes the given error to the response and sets appropriate HTTP status headers.
85107
func handleInternalError(response *restful.Response, err error) {
86108
response.AddHeader("Content-Type", "text/plain")

src/app/backend/deploy.go

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,9 @@ type AppDeployment struct {
3737

3838
// Whether the created service is external.
3939
IsExternal bool `json:"isExternal"`
40+
41+
// Target namespace of the application.
42+
Namespace string `json:"namespace"`
4043
}
4144

4245
// Port mapping for an application deployment.
@@ -79,7 +82,7 @@ func DeployApp(deployment *AppDeployment, client *client.Client) error {
7982
},
8083
}
8184

82-
_, err := client.ReplicationControllers(api.NamespaceDefault).Create(replicaSet)
85+
_, err := client.ReplicationControllers(deployment.Namespace).Create(replicaSet)
8386

8487
if err != nil {
8588
// TODO(bryk): Roll back created resources in case of error.
@@ -116,7 +119,7 @@ func DeployApp(deployment *AppDeployment, client *client.Client) error {
116119
service.Spec.Ports = append(service.Spec.Ports, servicePort)
117120
}
118121

119-
_, err = client.Services(api.NamespaceDefault).Create(service)
122+
_, err = client.Services(deployment.Namespace).Create(service)
120123

121124
// TODO(bryk): Roll back created resources in case of error.
122125

src/app/backend/namespacelist.go

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
// Copyright 2015 Google Inc. All Rights Reserved.
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package main
16+
17+
import (
18+
client "k8s.io/kubernetes/pkg/client/unversioned"
19+
"k8s.io/kubernetes/pkg/fields"
20+
"k8s.io/kubernetes/pkg/labels"
21+
)
22+
23+
// List of Namespaces in the cluster.
24+
type NamespacesList struct {
25+
// Unordered list of Namespaces.
26+
Namespaces []string `json:"namespaces"`
27+
}
28+
29+
// Returns a list of all namespaces in the cluster.
30+
func GetNamespaceList(client *client.Client) (*NamespacesList, error) {
31+
list, err := client.Namespaces().List(labels.Everything(), fields.Everything())
32+
33+
if err != nil {
34+
return nil, err
35+
}
36+
37+
namespaceList := &NamespacesList{}
38+
39+
for _, element := range list.Items {
40+
namespaceList.Namespaces = append(namespaceList.Namespaces, element.ObjectMeta.Name)
41+
}
42+
43+
return namespaceList, nil
44+
}

src/app/externs/angularresource.js

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,14 @@
2020
*/
2121

2222

23+
/**
24+
* @typedef {{
25+
* $promise: !angular.$q.Promise
26+
* }}
27+
*/
28+
angular.ResourceClass;
29+
30+
2331
/**
2432
* @typedef {function(string):!angular.Resource}
2533
*/
@@ -38,12 +46,23 @@ angular.Resource = function() {};
3846
* @param {!T} data
3947
* @param {function(!T)=} opt_callback
4048
* @param {function(!angular.$http.Response)=} opt_errback
49+
* @returns {!angular.ResourceClass}
4150
*/
4251
angular.Resource.prototype.save = function(data, opt_callback, opt_errback) {};
4352

4453

4554
/**
4655
* @param {function(!T)=} opt_callback
4756
* @param {function(!angular.$http.Response)=} opt_errback
57+
* @returns {!angular.ResourceClass}
4858
*/
4959
angular.Resource.prototype.get = function(opt_callback, opt_errback) {};
60+
61+
62+
/**
63+
* @param {function(!T)=} opt_callback
64+
* @param {function(!angular.$http.Response)=} opt_errback
65+
* @returns {!angular.ResourceClass}
66+
*/
67+
angular.Resource.prototype.query = function(opt_callback, opt_errback) {};
68+

src/app/externs/backendapi.js

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,8 @@ backendApi.PortMapping;
4242
* isExternal: boolean,
4343
* name: string,
4444
* portMappings: !Array<!backendApi.PortMapping>,
45-
* replicas: number
45+
* replicas: number,
46+
* namespace: string
4647
* }}
4748
*/
4849
backendApi.AppDeployment;
@@ -70,3 +71,10 @@ backendApi.ReplicaSetList;
7071
* }}
7172
*/
7273
backendApi.ReplicaSet;
74+
75+
/**
76+
* @typedef {{
77+
* namespaces: !Array<string>
78+
* }}
79+
*/
80+
backendApi.NamespaceList;

src/app/frontend/deploy/deploy.html

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,14 @@ <h3 class="md-headline">Deploy a Containerized App</h3>
5656
</md-select>
5757
</md-input-container>
5858
</div>
59+
<md-input-container class="md-block">
60+
<label>Namespace</label>
61+
<md-select ng-model="ctrl.namespace" required>
62+
<md-option ng-repeat="namespace in ctrl.namespaces" ng-value="namespace">
63+
{{namespace}}
64+
</md-option>
65+
</md-select>
66+
</md-input-container>
5967
<md-switch ng-model="ctrl.isExternal" class="md-primary">
6068
Expose service externally
6169
</md-switch>

src/app/frontend/deploy/deploy_controller.js

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,10 @@ export default class DeployController {
2323
* @param {!angular.$resource} $resource
2424
* @param {!angular.$log} $log
2525
* @param {!ui.router.$state} $state
26+
* @param {!backendApi.NamespaceList} namespaces
2627
* @ngInject
2728
*/
28-
constructor($resource, $log, $state) {
29+
constructor($resource, $log, $state, namespaces) {
2930
/** @export {string} */
3031
this.name = '';
3132

@@ -45,11 +46,23 @@ export default class DeployController {
4546
/** @export {!Array<!backendApi.PortMapping>} */
4647
this.portMappings = [this.newEmptyPortMapping_(this.protocols[0])];
4748

49+
/**
50+
* List of available namespaces.
51+
* @export {!Array<string>}
52+
*/
53+
this.namespaces = namespaces.namespaces;
54+
55+
/**
56+
* Currently chosen namespace.
57+
* @export {(string|undefined)}
58+
*/
59+
this.namespace = this.namespaces.length > 0 ? this.namespaces[0] : undefined;
60+
4861
/** @export {boolean} */
4962
this.isExternal = false;
5063

51-
/** @private {!angular.Resource<!backendApi.AppDeployment>} */
52-
this.resource_ = $resource('/api/deploy');
64+
/** @private {!angular.$resource} */
65+
this.resource_ = $resource;
5366

5467
/** @private {!angular.$log} */
5568
this.log_ = $log;
@@ -76,10 +89,14 @@ export default class DeployController {
7689
name: this.name,
7790
portMappings: this.portMappings.filter(this.isPortMappingEmpty_),
7891
replicas: this.replicas,
92+
namespace: this.namespace,
7993
};
8094

95+
/** @type {!angular.Resource<!backendApi.AppDeployment>} */
96+
let resource = this.resource_('/api/deploy');
97+
8198
this.isDeployInProgress_ = true;
82-
this.resource_.save(
99+
resource.save(
83100
deployAppConfig,
84101
(savedConfig) => {
85102
this.isDeployInProgress_ = false;

src/app/frontend/deploy/deploy_state.js

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,22 @@ export default function stateConfig($stateProvider) {
2626
controller: DeployController,
2727
controllerAs: 'ctrl',
2828
url: '/deploy',
29+
resolve: {
30+
namespaces: resolveNamespaces,
31+
},
2932
templateUrl: 'deploy/deploy.html',
3033
});
34+
35+
/**
36+
* Resolves namespaces for the deploy view.
37+
*
38+
* @param {!angular.$resource} $resource
39+
* @ngInject
40+
*/
41+
function resolveNamespaces($resource) {
42+
/** @type {!angular.Resource<!backendApi.NamespaceList>} */
43+
let resource = $resource('/api/namespace');
44+
45+
return resource.get().$promise;
46+
}
3147
}

0 commit comments

Comments
 (0)