提交 65875b44 编写于 作者: D Denis Poisson 提交者: Marcin Maciaszczyk

Status icons for Services visible on list and resources pages + no labels handled (#845)

上级 12511ace
......@@ -29,6 +29,7 @@ func ToService(service *api.Service) Service {
// TODO(maciaszczykm): Fill ExternalEndpoints with data.
Selector: service.Spec.Selector,
ClusterIP: service.Spec.ClusterIP,
Type: service.Spec.Type,
}
}
......
......@@ -17,6 +17,7 @@ package service
import (
"log"
"k8s.io/kubernetes/pkg/api"
client "k8s.io/kubernetes/pkg/client/unversioned"
"github.com/kubernetes/dashboard/resource/common"
......@@ -38,6 +39,9 @@ type Service struct {
// Label selector of the service.
Selector map[string]string `json:"selector"`
// Type determines how the service will be exposed. Valid options: ClusterIP, NodePort, LoadBalancer
Type api.ServiceType `json:"type"`
// ClusterIP is usually assigned by the master. Valid values are None, empty string (""), or
// a valid IP address. None can be specified for headless services when proxying is not required
ClusterIP string `json:"clusterIP"`
......
......@@ -407,6 +407,7 @@ backendApi.ServiceDetail;
* internalEndpoint: !backendApi.Endpoint,
* externalEndpoints: !Array<!backendApi.Endpoint>,
* selector: !Object<string, string>,
* type: string,
* clusterIP: string
* }}
*/
......
......@@ -14,12 +14,15 @@ See the License for the specific language governing permissions and
limitations under the License.
-->
<kd-middle-ellipsis display-string="{{::key}}: {{::value}}" class="kd-labels"
ng-repeat="(key, value) in ::labelsCtrl.labels"
ng-if="labelsCtrl.isVisible($index)">
</kd-middle-ellipsis>
<div class="kd-labels kd-labels-switch" ng-show="labelsCtrl.isMoreAvailable()"
ng-click="labelsCtrl.switchLabelsView()">
{{labelsCtrl.isShowingAll() ?
labelsCtrl.i18n.MSG_LABELS_SHOW_LESS_TOOLTIP : labelsCtrl.i18n.MSG_LABELS_SHOW_ALL_TOOLTIP}}
<div ng-if="::labelsCtrl.labels">
<kd-middle-ellipsis display-string="{{::key}}: {{::value}}" class="kd-labels"
ng-repeat="(key, value) in ::labelsCtrl.labels"
ng-if="labelsCtrl.isVisible($index)">
</kd-middle-ellipsis>
<div class="kd-labels kd-labels-switch" ng-show="labelsCtrl.isMoreAvailable()"
ng-click="labelsCtrl.switchLabelsView()">
{{labelsCtrl.isShowingAll() ?
labelsCtrl.i18n.MSG_LABELS_SHOW_LESS_TOOLTIP : labelsCtrl.i18n.MSG_LABELS_SHOW_ALL_TOOLTIP}}
</div>
</div>
<div ng-hide="::labelsCtrl.labels">-</div>
......@@ -27,6 +27,15 @@ limitations under the License.
<kd-resource-card ng-repeat="service in ::$ctrl.services"
object-meta="service.objectMeta" type-meta="service.typeMeta">
<kd-resource-card-status layout="row">
<md-icon class="material-icons" ng-if="::$ctrl.isPending(service)">
timelapse
<md-tooltip md-direction="right">{{::$ctrl.i18n.MSG_POD_IS_PENDING_TOOLTIP}}</md-tooltip>
</md-icon>
<md-icon class="material-icons kd-success" ng-if="::$ctrl.isSuccess(service)">
check_circle
</md-icon>
</kd-resource-card-status>
<kd-resource-card-columns>
<kd-resource-card-column>
<a ng-href="{{::$ctrl.getServiceDetailHref(service)}}">
......@@ -36,7 +45,9 @@ limitations under the License.
<kd-resource-card-column>
<kd-labels labels="::service.objectMeta.labels"></kd-labels>
</kd-resource-card-column>
<kd-resource-card-column>{{::service.clusterIP}}</kd-resource-card-column>
<kd-resource-card-column>
<div>{{::$ctrl.getServiceClusterIP(service)}}</div>
</kd-resource-card-column>
<kd-resource-card-column>
<div ng-if="::service.internalEndpoint">
<kd-internal-endpoint endpoint="::service.internalEndpoint"></kd-internal-endpoint>
......
......@@ -40,6 +40,37 @@ export class ServiceCardListController {
return this.state_.href(
stateName, new StateParams(service.objectMeta.namespace, service.objectMeta.name));
}
/**
* Returns true if Service has no assigned Cluster IP
* or if Service type is LoadBalancer or NodePort and doesn't have an external endpoint IP
* @param {!backendApi.Service} service
* @return {boolean}
* @export
*/
isPending(service) {
return service.clusterIP === null ||
((service.type === 'LoadBalancer' || service.type === 'NodePort') &&
service.externalEndpoints === null);
}
/**
* Returns true if Service has ClusterIP assigned and one of the following conditions is met:
* - Service type is LoadBalancer or NodePort and has an external endpoint IP
* - Service type is not LoadBalancer or NodePort
* @param {!backendApi.Service} service
* @return {boolean}
* @export
*/
isSuccess(service) { return !this.isPending(service); }
/**
* Returns the service's clusterIP or a dash ('-') if it is not yet set
* @param {!backendApi.Service} service
* @return {string}
* @export
*/
getServiceClusterIP(service) { return service.clusterIP ? service.clusterIP : '-'; }
}
/**
......@@ -76,4 +107,6 @@ const i18n = {
/** @export {string} @desc Label 'External endpoints' which appears as a column label in the
table of services (service list view). */
MSG_SERVICE_LIST_EXTERNAL_ENDPOINTS_LABEL: goog.getMsg('External endpoints'),
/** @export {string} @desc tooltip for pending pod card icon */
MSG_SERVICE_IS_PENDING_TOOLTIP: goog.getMsg('This service is in a pending state.'),
};
......@@ -16,6 +16,6 @@ limitations under the License.
<kd-content-card>
<kd-content>
<kd-service-card-list services="::ctrl.serviceList.services"></kd-service-card-list>
<kd-service-card-list services="::ctrl.serviceList.services" with-statuses="true"></kd-service-card-list>
</kd-content>
</kd-content-card>
......@@ -11,6 +11,7 @@
// 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 replicationControllerListModule from 'replicationcontrollerlist/replicationcontrollerlist_module';
describe('Replication controller card', () => {
......
......@@ -38,4 +38,73 @@ describe('Service list controller', () => {
},
})).toBe('#/service/foo-namespace/foo-service');
});
it('should return true when service.clusterIP is null', () => {
expect(ctrl.isPending({
clusterIP: null,
})).toBeTruthy();
});
it('should return false when service.clusterIP is set', () => {
expect(ctrl.isPending({
clusterIP: '10.67.252.103',
})).toBeFalsy();
});
it('should return true when service.type is LoadBalancer AND service.externalEndpoints is null',
() => {
expect(ctrl.isPending({
clusterIP: '10.67.252.103',
type: 'LoadBalancer',
externalEndpoints: null,
})).toBeTruthy();
});
it('should return true when service.type is NodePort AND service.externalEndpoints is null',
() => {
expect(ctrl.isPending({
clusterIP: '10.67.252.103',
type: 'NodePort',
externalEndpoints: null,
})).toBeTruthy();
});
it('should return true when service.type is LoadBalancer AND service.externalEndpoints is set',
() => {
expect(ctrl.isSuccess({
clusterIP: '10.67.252.103',
type: 'LoadBalancer',
externalEndpoints: ['10.64.0.4:80', '10.64.1.5:80', '10.64.2.4:80'],
})).toBeTruthy();
});
it('should return true when service.type is NodePort AND service.externalEndpoints is set',
() => {
expect(ctrl.isSuccess({
clusterIP: '10.67.252.103',
type: 'NodePort',
externalEndpoints: ['10.64.0.4:80', '10.64.1.5:80', '10.64.2.4:80'],
})).toBeTruthy();
});
it('should return true when service.type is ClusterIP and service.externalEndpoints is null',
() => {
expect(ctrl.isSuccess({
clusterIP: '10.67.252.103',
type: 'ClusterIP',
externalEndpoints: null,
})).toBeTruthy();
});
it('should return the service clusterIP when teh clusterIP is set', () => {
expect(ctrl.getServiceClusterIP({
clusterIP: '10.67.252.103',
})).toBe('10.67.252.103');
});
it('should return the service clusterIP when teh clusterIP is set', () => {
expect(ctrl.getServiceClusterIP({
clusterIP: null,
})).toBe('-');
});
});
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册