Skip to content

Commit 24fce07

Browse files
Sebastian FlorekSebastian Florek
authored andcommitted
Added option to delete services related to replication controller while deleting RC.
1 parent 04453c0 commit 24fce07

11 files changed

+411
-72
lines changed

src/app/backend/apihandler.go

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -297,13 +297,20 @@ func (apiHandler *ApiHandler) handleUpdateReplicasCount(
297297
}
298298

299299
// Handles delete Replication Controller API call.
300+
// TODO(floreks): there has to be some kind of transaction here
300301
func (apiHandler *ApiHandler) handleDeleteReplicationController(
301302
request *restful.Request, response *restful.Response) {
302303

303304
namespace := request.PathParameter("namespace")
304305
replicationController := request.PathParameter("replicationController")
306+
deleteServices, err := strconv.ParseBool(request.QueryParameter("deleteServices"))
307+
if err != nil {
308+
handleInternalError(response, err)
309+
return
310+
}
305311

306-
if err := DeleteReplicationControllerWithPods(apiHandler.client, namespace, replicationController); err != nil {
312+
if err := DeleteReplicationController(apiHandler.client, namespace,
313+
replicationController, deleteServices); err != nil {
307314
handleInternalError(response, err)
308315
return
309316
}

src/app/backend/replicationcontrollercommon.go

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ package main
1717
import (
1818
"k8s.io/kubernetes/pkg/api"
1919
"k8s.io/kubernetes/pkg/api/unversioned"
20+
"k8s.io/kubernetes/pkg/apis/extensions"
2021
client "k8s.io/kubernetes/pkg/client/unversioned"
2122
"k8s.io/kubernetes/pkg/fields"
2223
"k8s.io/kubernetes/pkg/labels"
@@ -103,3 +104,47 @@ func getReplicationControllerPodInfo(replicationController *api.ReplicationContr
103104

104105
return result
105106
}
107+
108+
// Transforms simple selector map to labels.Selector object that can be used when querying for
109+
// object.
110+
func toLabelSelector(selector map[string]string) (labels.Selector, error) {
111+
labelSelector, err := extensions.LabelSelectorAsSelector(&extensions.LabelSelector{MatchLabels: selector})
112+
113+
if err != nil {
114+
return nil, err
115+
}
116+
117+
return labelSelector, nil
118+
}
119+
120+
// Based on given selector returns list of services that are candidates for deletion.
121+
// Services are matched by replication controllers' label selector. They are deleted if given
122+
// label selector is targeting only 1 replication controller.
123+
func getServicesForDeletion(client client.Interface, labelSelector labels.Selector,
124+
namespace string) ([]api.Service, error) {
125+
126+
replicationControllers, err := client.ReplicationControllers(namespace).List(unversioned.ListOptions{
127+
LabelSelector: unversioned.LabelSelector{labelSelector},
128+
FieldSelector: unversioned.FieldSelector{fields.Everything()},
129+
})
130+
if err != nil {
131+
return nil, err
132+
}
133+
134+
// if label selector is targeting only 1 replication controller
135+
// then we can delete services targeted by this label selector,
136+
// otherwise we can not delete any services so just return empty list
137+
if len(replicationControllers.Items) != 1 {
138+
return []api.Service{}, nil
139+
}
140+
141+
services, err := client.Services(namespace).List(unversioned.ListOptions{
142+
LabelSelector: unversioned.LabelSelector{labelSelector},
143+
FieldSelector: unversioned.FieldSelector{fields.Everything()},
144+
})
145+
if err != nil {
146+
return nil, err
147+
}
148+
149+
return services.Items, nil
150+
}

src/app/backend/replicationcontrollerdetail.go

Lines changed: 44 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -186,12 +186,20 @@ func GetReplicationControllerDetail(client client.Interface, heapsterClient Heap
186186
return replicationControllerDetail, nil
187187
}
188188

189-
// TODO(floreks): This should be transactional to make sure that RC will not be deleted without
190-
// TODO(floreks): Should related services be deleted also?
191-
// Deletes replication controller with given name in given namespace and related pods
192-
func DeleteReplicationControllerWithPods(client client.Interface, namespace, name string) error {
189+
// TODO(floreks): This should be transactional to make sure that RC will not be deleted without pods
190+
// Deletes replication controller with given name in given namespace and related pods.
191+
// Also deletes services related to replication controller if deleteServices is true.
192+
func DeleteReplicationController(client client.Interface, namespace, name string,
193+
deleteServices bool) error {
194+
193195
log.Printf("Deleting %s replication controller from %s namespace", name, namespace)
194196

197+
if deleteServices {
198+
if err := DeleteReplicationControllerServices(client, namespace, name); err != nil {
199+
return err
200+
}
201+
}
202+
195203
pods, err := getRawReplicationControllerPods(client, namespace, name)
196204
if err != nil {
197205
return err
@@ -212,6 +220,38 @@ func DeleteReplicationControllerWithPods(client client.Interface, namespace, nam
212220
return nil
213221
}
214222

223+
// Deletes services related to replication controller with given name in given namespace.
224+
func DeleteReplicationControllerServices(client client.Interface, namespace, name string) error {
225+
log.Printf("Deleting services related to %s replication controller from %s namespace", name,
226+
namespace)
227+
228+
replicationController, err := client.ReplicationControllers(namespace).Get(name)
229+
if err != nil {
230+
return err
231+
}
232+
233+
labelSelector, err := toLabelSelector(replicationController.Spec.Selector)
234+
if err != nil {
235+
return err
236+
}
237+
238+
services, err := getServicesForDeletion(client, labelSelector, namespace)
239+
if err != nil {
240+
return err
241+
}
242+
243+
for _, service := range services {
244+
if err := client.Services(namespace).Delete(service.Name); err != nil {
245+
return err
246+
}
247+
}
248+
249+
log.Printf("Successfully deleted services related to %s replication controller from %s namespace",
250+
name, namespace)
251+
252+
return nil
253+
}
254+
215255
// Updates number of replicas in Replication Controller based on Replication Controller Spec
216256
func UpdateReplicasCount(client client.Interface, namespace, name string,
217257
replicationControllerSpec *ReplicationControllerSpec) error {

src/app/externs/backendapi.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,13 @@ backendApi.ReplicationControllerDetail;
155155
*/
156156
backendApi.ReplicationControllerSpec;
157157

158+
/**
159+
* @typedef {{
160+
* deleteServices: boolean
161+
* }}
162+
*/
163+
backendApi.DeleteReplicationControllerSpec;
164+
158165
/**
159166
* @typedef {{
160167
* name: string,

src/app/frontend/replicationcontrollerdetail/deletereplicationcontroller.html

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,14 @@ <h4 class="md-title">Delete Replication Controller</h4>
2121
Delete replication controller {{::ctrl.replicationController}} in namespace {{::ctrl.namespace}}.<br>
2222
Pods managed by the replication controller will be also deleted.
2323
</div>
24+
<md-checkbox ng-model="ctrl.deleteServices" class="kd-deletedialog-services-checkbox">
25+
Delete related services
26+
<md-icon class="material-icons kd-deletedialog-info-icon">
27+
info
28+
<md-tooltip>Services with label selector matching only this replication controller
29+
will be deleted</md-tooltip>
30+
</md-icon>
31+
</md-checkbox>
2432
<md-dialog-actions>
2533
<md-button class="md-primary" ng-click="ctrl.cancel()">Cancel</md-button>
2634
<md-button class="md-primary" ng-click="ctrl.remove()">Delete</md-button>
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
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+
@import '../variables';
16+
17+
md-checkbox {
18+
&.kd-deletedialog-services-checkbox {
19+
margin: $baseline-grid 0 0 $baseline-grid;
20+
}
21+
}
22+
23+
.kd-deletedialog-info-icon {
24+
font-size: $subhead-font-size-base;
25+
height: $subhead-font-size-base;
26+
margin-left: $baseline-grid / 2;
27+
}

src/app/frontend/replicationcontrollerdetail/deletereplicationcontroller_controller.js

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,9 @@ export default class DeleteReplicationControllerDialogController {
3535
/** @export {string} */
3636
this.namespace = namespace;
3737

38+
/** @export {boolean} */
39+
this.deleteServices = false;
40+
3841
/** @private {!md.$dialog} */
3942
this.mdDialog_ = $mdDialog;
4043

@@ -50,7 +53,15 @@ export default class DeleteReplicationControllerDialogController {
5053
remove() {
5154
let resource = getReplicationControllerDetailsResource(
5255
new StateParams(this.namespace, this.replicationController), this.resource_);
53-
resource.remove(() => { this.mdDialog_.hide(); }, () => { this.mdDialog_.cancel(); });
56+
57+
/** @type {!backendApi.DeleteReplicationControllerSpec} */
58+
let deleteReplicationControllerSpec = {
59+
deleteServices: this.deleteServices,
60+
};
61+
62+
resource.remove(
63+
deleteReplicationControllerSpec, () => { this.mdDialog_.hide(); },
64+
() => { this.mdDialog_.cancel(); });
5465
}
5566

5667
/**

src/test/backend/replicasetcommon_test.go

Lines changed: 0 additions & 63 deletions
This file was deleted.

0 commit comments

Comments
 (0)