Skip to content

Commit 64f698b

Browse files
committed
Merge pull request #732 from floreks/refactor-service-backend
Refactor services backend
2 parents 469903c + 88a208d commit 64f698b

File tree

11 files changed

+311
-137
lines changed

11 files changed

+311
-137
lines changed

src/app/backend/handler/apihandler.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -262,8 +262,8 @@ func CreateHttpApiHandler(client *client.Client, heapsterClient HeapsterClient,
262262
Writes(resourceService.ServiceList{}))
263263
servicesWs.Route(
264264
servicesWs.GET("/{namespace}/{service}").
265-
To(apiHandler.handleGetService).
266-
Writes(resourceService.Service{}))
265+
To(apiHandler.handleGetServiceDetail).
266+
Writes(resourceService.ServiceDetail{}))
267267
wsContainer.Add(servicesWs)
268268

269269
return wsContainer
@@ -281,10 +281,10 @@ func (apiHandler *ApiHandler) handleGetServiceList(request *restful.Request, res
281281
}
282282

283283
// Handles get service detail API call.
284-
func (apiHandler *ApiHandler) handleGetService(request *restful.Request, response *restful.Response) {
284+
func (apiHandler *ApiHandler) handleGetServiceDetail(request *restful.Request, response *restful.Response) {
285285
namespace := request.PathParameter("namespace")
286286
service := request.PathParameter("service")
287-
result, err := resourceService.GetService(apiHandler.client, namespace, service)
287+
result, err := resourceService.GetServiceDetail(apiHandler.client, namespace, service)
288288
if err != nil {
289289
handleInternalError(response, err)
290290
return

src/app/backend/resource/replicationcontroller/replicationcontrollerdetail.go

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ type ReplicationControllerDetail struct {
4545
Pods pod.PodList `json:"pods"`
4646

4747
// Detailed information about service related to Replication Controller.
48-
Services []resourceService.Service `json:"services"`
48+
ServiceList resourceService.ServiceList `json:"serviceList"`
4949

5050
// True when the data contains at least one pod with metrics information, false otherwise.
5151
HasMetrics bool `json:"hasMetrics"`
@@ -89,12 +89,14 @@ func GetReplicationControllerDetail(client k8sClient.Interface, heapsterClient c
8989
TypeMeta: common.CreateTypeMeta(replicationController.TypeMeta),
9090
LabelSelector: replicationController.Spec.Selector,
9191
PodInfo: getReplicationPodInfo(replicationController, pods.Items),
92+
ServiceList: resourceService.ServiceList{Services: make([]resourceService.Service, 0)},
9293
}
9394

9495
matchingServices := getMatchingServices(services.Items, replicationController)
9596

9697
for _, service := range matchingServices {
97-
replicationControllerDetail.Services = append(replicationControllerDetail.Services,
98+
replicationControllerDetail.ServiceList.Services = append(
99+
replicationControllerDetail.ServiceList.Services,
98100
getService(service, *replicationController, pods.Items, nodes.Items))
99101
}
100102

@@ -204,10 +206,10 @@ func UpdateReplicasCount(client k8sClient.Interface, namespace, name string,
204206
func getService(service api.Service, replicationController api.ReplicationController,
205207
pods []api.Pod, nodes []api.Node) resourceService.Service {
206208

207-
result := resourceService.GetServiceDetails(&service);
209+
result := resourceService.ToService(&service)
208210
result.ExternalEndpoints = getExternalEndpoints(replicationController, pods, service, nodes)
209211

210-
return result;
212+
return result
211213
}
212214

213215
// Returns array of external endpoints for a replication controller.
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
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 service
16+
17+
import (
18+
"k8s.io/kubernetes/pkg/api"
19+
20+
"github.com/kubernetes/dashboard/resource/common"
21+
)
22+
23+
// ToService returns api service object based on kubernetes service object
24+
func ToService(service *api.Service) Service {
25+
return Service{
26+
ObjectMeta: common.CreateObjectMeta(service.ObjectMeta),
27+
TypeMeta: common.CreateTypeMeta(service.TypeMeta),
28+
InternalEndpoint: common.GetInternalEndpoint(service.Name, service.Namespace, service.Spec.Ports),
29+
// TODO(maciaszczykm): Fill ExternalEndpoints with data.
30+
Selector: service.Spec.Selector,
31+
ClusterIP: service.Spec.ClusterIP,
32+
}
33+
}
34+
35+
// ToServiceDetails returns api service object based on kubernetes service object
36+
func ToServiceDetail(service *api.Service) ServiceDetail {
37+
return ServiceDetail{
38+
ObjectMeta: common.CreateObjectMeta(service.ObjectMeta),
39+
TypeMeta: common.CreateTypeMeta(service.TypeMeta),
40+
InternalEndpoint: common.GetInternalEndpoint(service.Name, service.Namespace, service.Spec.Ports),
41+
// TODO(maciaszczykm): Fill ExternalEndpoints with data.
42+
Selector: service.Spec.Selector,
43+
ClusterIP: service.Spec.ClusterIP,
44+
Type: service.Spec.Type,
45+
}
46+
}
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
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 service
16+
17+
import (
18+
"log"
19+
20+
"k8s.io/kubernetes/pkg/api"
21+
client "k8s.io/kubernetes/pkg/client/unversioned"
22+
23+
"github.com/kubernetes/dashboard/resource/common"
24+
)
25+
26+
// Service is a representation of a service.
27+
type ServiceDetail struct {
28+
ObjectMeta common.ObjectMeta `json:"objectMeta"`
29+
TypeMeta common.TypeMeta `json:"typeMeta"`
30+
31+
// InternalEndpoint of all Kubernetes services that have the same label selector as connected Replication
32+
// Controller. Endpoint is DNS name merged with ports.
33+
InternalEndpoint common.Endpoint `json:"internalEndpoint"`
34+
35+
// ExternalEndpoints of all Kubernetes services that have the same label selector as connected Replication
36+
// Controller. Endpoint is external IP address name merged with ports.
37+
ExternalEndpoints []common.Endpoint `json:"externalEndpoints"`
38+
39+
// Label selector of the service.
40+
Selector map[string]string `json:"selector"`
41+
42+
// Type determines how the service will be exposed. Valid options: ClusterIP, NodePort, LoadBalancer
43+
Type api.ServiceType `json:"type"`
44+
45+
// ClusterIP is usually assigned by the master. Valid values are None, empty string (""), or
46+
// a valid IP address. None can be specified for headless services when proxying is not required
47+
ClusterIP string `json:"clusterIP"`
48+
}
49+
50+
// GetServiceDetail gets service details.
51+
func GetServiceDetail(client client.Interface, namespace, name string) (*ServiceDetail, error) {
52+
log.Printf("Getting details of %s service in %s namespace", name, namespace)
53+
54+
// TODO(maciaszczykm): Use channels.
55+
serviceData, err := client.Services(namespace).Get(name)
56+
if err != nil {
57+
return nil, err
58+
}
59+
60+
service := ToServiceDetail(serviceData)
61+
return &service, nil
62+
}

src/app/backend/resource/service/services.go renamed to src/app/backend/resource/service/servicelist.go

Lines changed: 3 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,9 @@ package service
1717
import (
1818
"log"
1919

20-
"github.com/kubernetes/dashboard/resource/common"
21-
"k8s.io/kubernetes/pkg/api"
2220
client "k8s.io/kubernetes/pkg/client/unversioned"
21+
22+
"github.com/kubernetes/dashboard/resource/common"
2323
)
2424

2525
// Service is a representation of a service.
@@ -38,9 +38,6 @@ type Service struct {
3838
// Label selector of the service.
3939
Selector map[string]string `json:"selector"`
4040

41-
// Type determines how the service will be exposed. Valid options: ClusterIP, NodePort, LoadBalancer
42-
Type api.ServiceType `json:"type"`
43-
4441
// ClusterIP is usually assigned by the master. Valid values are None, empty string (""), or
4542
// a valid IP address. None can be specified for headless services when proxying is not required
4643
ClusterIP string `json:"clusterIP"`
@@ -52,20 +49,6 @@ type ServiceList struct {
5249
Services []Service `json:"services"`
5350
}
5451

55-
// GetService gets service details.
56-
func GetService(client client.Interface, namespace, name string) (*Service, error) {
57-
log.Printf("Getting details of %s service in %s namespace", name, namespace)
58-
59-
// TODO(maciaszczykm): Use channels.
60-
serviceData, err := client.Services(namespace).Get(name)
61-
if err != nil {
62-
return nil, err
63-
}
64-
65-
service := GetServiceDetails(serviceData)
66-
return &service, nil
67-
}
68-
6952
// GetServiceList returns a list of all services in the cluster.
7053
func GetServiceList(client client.Interface) (*ServiceList, error) {
7154
log.Printf("Getting list of all services in the cluster")
@@ -81,21 +64,8 @@ func GetServiceList(client client.Interface) (*ServiceList, error) {
8164

8265
serviceList := &ServiceList{Services: make([]Service, 0)}
8366
for _, service := range services.Items {
84-
serviceList.Services = append(serviceList.Services, GetServiceDetails(&service))
67+
serviceList.Services = append(serviceList.Services, ToService(&service))
8568
}
8669

8770
return serviceList, nil
8871
}
89-
90-
// GetServiceDetails returns api service object based on kubernetes service object
91-
func GetServiceDetails(service *api.Service) Service {
92-
return Service{
93-
ObjectMeta: common.CreateObjectMeta(service.ObjectMeta),
94-
TypeMeta: common.CreateTypeMeta(service.TypeMeta),
95-
InternalEndpoint: common.GetInternalEndpoint(service.Name, service.Namespace, service.Spec.Ports),
96-
// TODO(maciaszczykm): Fill ExternalEndpoints with data.
97-
Selector: service.Spec.Selector,
98-
ClusterIP: service.Spec.ClusterIP,
99-
Type: service.Spec.Type,
100-
}
101-
}

src/app/externs/backendapi.js

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -214,7 +214,7 @@ backendApi.TypeMeta;
214214
* containerImages: !Array<string>,
215215
* podInfo: !backendApi.PodInfo,
216216
* pods: !backendApi.PodList,
217-
* services: !Array<!backendApi.ServiceDetail>,
217+
* serviceList: !backendApi.ServiceList,
218218
* hasMetrics: boolean
219219
* }}
220220
*/
@@ -254,16 +254,27 @@ backendApi.Pod;
254254
* internalEndpoint: !backendApi.Endpoint,
255255
* externalEndpoints: !Array<!backendApi.Endpoint>,
256256
* selector: !Object<string, string>,
257-
* labels: !Object<string, string>,
258-
* clusterIP: string,
259-
* type: string
257+
* type: string,
258+
* clusterIP: string
260259
* }}
261260
*/
262261
backendApi.ServiceDetail;
263262

264263
/**
265264
* @typedef {{
266-
* services: !Array<backendApi.ServiceDetail>
265+
* objectMeta: !backendApi.ObjectMeta,
266+
* typeMeta: !backendApi.TypeMeta,
267+
* internalEndpoint: !backendApi.Endpoint,
268+
* externalEndpoints: !Array<!backendApi.Endpoint>,
269+
* selector: !Object<string, string>,
270+
* clusterIP: string
271+
* }}
272+
*/
273+
backendApi.Service;
274+
275+
/**
276+
* @typedef {{
277+
* services: !Array<backendApi.Service>
267278
* }}
268279
*/
269280
backendApi.ServiceList;

src/app/frontend/replicationcontrollerdetail/replicationcontrollerdetail.html

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,11 @@
2121
<kd-replication-controller-info replication-controller="::ctrl.replicationControllerDetail">
2222
</kd-replication-controller-info>
2323

24-
<kd-content-card ng-if="::ctrl.replicationControllerDetail.services">
24+
<kd-content-card ng-if="::ctrl.replicationControllerDetail.serviceList.services">
2525
<kd-title>Services</kd-title>
2626
<kd-content>
27-
<kd-service-card-list services="::ctrl.replicationControllerDetail.services">
27+
<kd-service-card-list
28+
services="::ctrl.replicationControllerDetail.serviceList.services">
2829
</kd-service-card-list>
2930
</kd-content>
3031
</kd-content-card>

src/app/frontend/servicelist/servicecardlist_component.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ export class ServiceCardListController {
2525
constructor($state) { this.state_ = $state; }
2626

2727
/**
28-
* @param {!backendApi.ServiceDetail} service
28+
* @param {!backendApi.Service} service
2929
* @return {string}
3030
* @export
3131
*/
@@ -44,7 +44,7 @@ export const serviceCardListComponent = {
4444
templateUrl: 'servicelist/servicecardlist.html',
4545
controller: ServiceCardListController,
4646
bindings: {
47-
/** {!Array<!backendApi.ServiceDetail>} */
47+
/** {!Array<!backendApi.Service>} */
4848
'services': '<',
4949
/** {boolean} */
5050
'selectable': '<',
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
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 service
16+
17+
import (
18+
"reflect"
19+
"testing"
20+
21+
"k8s.io/kubernetes/pkg/api"
22+
23+
"github.com/kubernetes/dashboard/resource/common"
24+
)
25+
26+
func TestToServiceDetail(t *testing.T) {
27+
cases := []struct {
28+
service *api.Service
29+
expected ServiceDetail
30+
}{
31+
{
32+
service: &api.Service{}, expected: ServiceDetail{},
33+
}, {
34+
service: &api.Service{
35+
ObjectMeta: api.ObjectMeta{
36+
Name: "test-service", Namespace: "test-namespace",
37+
}},
38+
expected: ServiceDetail{
39+
ObjectMeta: common.ObjectMeta{
40+
Name: "test-service",
41+
Namespace: "test-namespace",
42+
},
43+
InternalEndpoint: common.Endpoint{Host: "test-service.test-namespace"},
44+
},
45+
},
46+
}
47+
48+
for _, c := range cases {
49+
actual := ToServiceDetail(c.service)
50+
51+
if !reflect.DeepEqual(actual, c.expected) {
52+
t.Errorf("ToServiceDetail(%#v) == \ngot %#v, \nexpected %#v", c.service, actual,
53+
c.expected)
54+
}
55+
}
56+
}
57+
58+
func TestToService(t *testing.T) {
59+
cases := []struct {
60+
service *api.Service
61+
expected Service
62+
}{
63+
{
64+
service: &api.Service{}, expected: Service{},
65+
}, {
66+
service: &api.Service{
67+
ObjectMeta: api.ObjectMeta{
68+
Name: "test-service", Namespace: "test-namespace",
69+
}},
70+
expected: Service{
71+
ObjectMeta: common.ObjectMeta{
72+
Name: "test-service",
73+
Namespace: "test-namespace",
74+
},
75+
InternalEndpoint: common.Endpoint{Host: "test-service.test-namespace"},
76+
},
77+
},
78+
}
79+
80+
for _, c := range cases {
81+
actual := ToService(c.service)
82+
83+
if !reflect.DeepEqual(actual, c.expected) {
84+
t.Errorf("ToService(%#v) == \ngot %#v, \nexpected %#v", c.service, actual,
85+
c.expected)
86+
}
87+
}
88+
}

0 commit comments

Comments
 (0)