Skip to content

Commit fe5187b

Browse files
committed
Updates for Service Instance & Bindings
Updates for service instances. Prep to allow updates to chosen parameters for instance and bindings.
1 parent 44d587b commit fe5187b

21 files changed

+1074
-274
lines changed

app/index.html

+4-1
Original file line numberDiff line numberDiff line change
@@ -224,6 +224,7 @@ <h1>JavaScript Required</h1>
224224
<script src="scripts/services/resourceAlerts.js"></script>
225225
<script src="scripts/services/listRowUtils.js"></script>
226226
<script src="scripts/services/ownerReferences.js"></script>
227+
<script src="scripts/services/serviceInstances.js"></script>
227228
<script src="scripts/controllers/landingPage.js"></script>
228229
<script src="scripts/services/events.js"></script>
229230
<script src="scripts/controllers/projects.js"></script>
@@ -248,6 +249,8 @@ <h1>JavaScript Required</h1>
248249
<script src="scripts/controllers/statefulSet.js"></script>
249250
<script src="scripts/controllers/services.js"></script>
250251
<script src="scripts/controllers/service.js"></script>
252+
<script src="scripts/controllers/serviceInstances.js"></script>
253+
<script src="scripts/controllers/serviceInstance.js"></script>
251254
<script src="scripts/controllers/secrets.js"></script>
252255
<script src="scripts/controllers/secret.js"></script>
253256
<script src="scripts/controllers/createSecret.js"></script>
@@ -359,6 +362,7 @@ <h1>JavaScript Required</h1>
359362
<script src="scripts/directives/fromFileDialog.js"></script>
360363
<script src="scripts/directives/create/nextSteps.js"></script>
361364
<script src="scripts/directives/imageNames.js"></script>
365+
<script src="scripts/directives/serviceBinding.js"></script>
362366

363367
<!-- New Overview -->
364368
<script src="scripts/directives/buildCounts.js"></script>
@@ -371,7 +375,6 @@ <h1>JavaScript Required</h1>
371375
<script src="scripts/directives/overview/networking.js"></script>
372376
<script src="scripts/directives/overview/pipelines.js"></script>
373377
<script src="scripts/directives/overview/serviceBindings.js"></script>
374-
<script src="scripts/directives/overview/serviceBinding.js"></script>
375378

376379
<script src="scripts/directives/istagSelect.js"></script>
377380
<script src="scripts/directives/deployImage.js"></script>

app/scripts/app.js

+10
Original file line numberDiff line numberDiff line change
@@ -272,6 +272,16 @@ angular
272272
controller: 'ServiceController',
273273
reloadOnSearch: false
274274
})
275+
.when('/project/:project/browse/service-instances', {
276+
templateUrl: 'views/service-instances.html',
277+
controller: 'ServiceInstancesController',
278+
reloadOnSearch: false
279+
})
280+
.when('/project/:project/browse/service-instances/:instance', {
281+
templateUrl: 'views/browse/service-instance.html',
282+
controller: 'ServiceInstanceController',
283+
reloadOnSearch: false
284+
})
275285
.when('/project/:project/browse/storage', {
276286
templateUrl: 'views/storage.html',
277287
controller: 'StorageController',

app/scripts/constants.js

+12
Original file line numberDiff line numberDiff line change
@@ -261,6 +261,18 @@ angular.extend(window.OPENSHIFT_CONSTANTS, {
261261
"/create-route",
262262
"/edit/routes/"
263263
]
264+
},
265+
{
266+
label: "Provisioned Services",
267+
href: "/browse/service-instances",
268+
prefixes: [
269+
"/browse/service-instances/"
270+
],
271+
canI: {
272+
resource: 'serviceinstances',
273+
group: 'servicecatalog.k8s.io',
274+
verb: 'list'
275+
}
264276
}
265277
]
266278
}
+107
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
'use strict';
2+
3+
angular.module('openshiftConsole')
4+
.controller('ServiceInstanceController', function ($scope,
5+
$filter,
6+
$routeParams,
7+
DataService,
8+
ProjectsService,
9+
ServiceInstancesService) {
10+
$scope.alerts = {};
11+
$scope.projectName = $routeParams.project;
12+
$scope.serviceInstance = null;
13+
$scope.serviceClass = null;
14+
$scope.serviceClasses = null;
15+
16+
$scope.breadcrumbs = [
17+
{
18+
title: "Provisioned Services",
19+
link: "project/" + $routeParams.project + "/browse/service-instances"
20+
}
21+
];
22+
23+
$scope.deprovision = function() {
24+
ServiceInstancesService.deprovision($scope.serviceInstance);
25+
};
26+
27+
var watches = [];
28+
29+
var updateBreadcrumbs = function() {
30+
if(!$scope.serviceInstance || !$scope.serviceClasses) {
31+
return;
32+
}
33+
34+
$scope.breadcrumbs.push({
35+
title: $filter('serviceInstanceDisplayName')($scope.serviceInstance, $scope.serviceClasses)
36+
});
37+
};
38+
39+
var updateServiceClassMetadata = function() {
40+
if(!$scope.serviceInstance || !$scope.serviceClasses) {
41+
return;
42+
}
43+
44+
var serviceClassName = _.get($scope.serviceInstance.spec, 'serviceClassName');
45+
$scope.serviceClass = _.get($scope.serviceClasses, [serviceClassName]);
46+
$scope.plan = _.find(_.get($scope.serviceClass, 'plans'), {name: $scope.serviceInstance.spec.planName });
47+
};
48+
49+
var serviceResolved = function(service, action) {
50+
$scope.loaded = true;
51+
$scope.serviceInstance = service;
52+
53+
if (action === "DELETED") {
54+
$scope.alerts["deleted"] = {
55+
type: "warning",
56+
message: "This provisioned service has been deleted."
57+
};
58+
}
59+
60+
updateServiceClassMetadata();
61+
};
62+
63+
ProjectsService
64+
.get($routeParams.project)
65+
.then(_.spread(function(project, context) {
66+
$scope.project = project;
67+
$scope.projectContext = context;
68+
69+
DataService
70+
.get({
71+
group: 'servicecatalog.k8s.io',
72+
resource: 'serviceinstances'
73+
}, $routeParams.instance, context, { errorNotification: false })
74+
.then(function(service) {
75+
76+
serviceResolved(service);
77+
updateBreadcrumbs();
78+
79+
watches.push(DataService.watchObject({
80+
group: 'servicecatalog.k8s.io',
81+
resource: 'serviceinstances'
82+
}, $routeParams.instance, context, serviceResolved));
83+
84+
}, function(error) {
85+
$scope.loaded = true;
86+
$scope.alerts["load"] = {
87+
type: "error",
88+
message: "The service details could not be loaded.",
89+
details: $filter('getErrorDetails')(error)
90+
};
91+
});
92+
93+
DataService.list({
94+
group: 'servicecatalog.k8s.io',
95+
resource: 'serviceclasses'
96+
}, context, function(serviceClasses) {
97+
$scope.serviceClasses = serviceClasses.by('metadata.name');
98+
updateServiceClassMetadata();
99+
updateBreadcrumbs();
100+
});
101+
102+
$scope.$on('$destroy', function(){
103+
DataService.unwatchAll(watches);
104+
});
105+
106+
}));
107+
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
'use strict';
2+
3+
angular.module('openshiftConsole')
4+
.controller('ServiceInstancesController', function ($scope,
5+
$filter,
6+
$routeParams,
7+
APIService,
8+
BindingService,
9+
Constants,
10+
DataService,
11+
LabelFilter,
12+
Logger,
13+
ProjectsService) {
14+
$scope.alerts = {};
15+
$scope.bindingsByInstanceRef = {};
16+
$scope.emptyMessage = "Loading...";
17+
$scope.labelSuggestions = {};
18+
$scope.projectName = $routeParams.project;
19+
$scope.serviceClasses = {};
20+
$scope.serviceInstances = {};
21+
$scope.unfilteredServiceInstances = {};
22+
23+
var watches = [];
24+
25+
var updateFilter = function() {
26+
$scope.serviceInstances = LabelFilter.getLabelSelector().select($scope.unfilteredServiceInstances);
27+
};
28+
29+
var sortServiceInstances = function() {
30+
$scope.unfilteredServiceInstances = BindingService.sortServiceInstances($scope.unfilteredServiceInstances, $scope.serviceClasses);
31+
};
32+
33+
ProjectsService
34+
.get($routeParams.project)
35+
.then(_.spread(function(project, context) {
36+
$scope.project = project;
37+
$scope.projectContext = context;
38+
39+
watches.push(DataService.watch({
40+
group: 'servicecatalog.k8s.io',
41+
resource: 'serviceinstancecredentials'
42+
}, context, function(bindings) {
43+
var bindingsByName = bindings.by('metadata.name');
44+
$scope.bindingsByInstanceRef = _.groupBy(bindingsByName, 'spec.instanceRef.name');
45+
}));
46+
47+
watches.push(DataService.watch({
48+
group: 'servicecatalog.k8s.io',
49+
resource: 'serviceinstances'
50+
}, context, function(serviceInstances) {
51+
$scope.emptyMessage = "No provisioned services to show";
52+
$scope.unfilteredServiceInstances = serviceInstances.by('metadata.name');
53+
54+
sortServiceInstances();
55+
updateFilter();
56+
updateFilterWarning();
57+
58+
LabelFilter.addLabelSuggestionsFromResources($scope.unfilteredServiceInstances, $scope.labelSuggestions);
59+
LabelFilter.setLabelSuggestions($scope.labelSuggestions);
60+
61+
Logger.log("provisioned services (subscribe)", $scope.unfilteredServiceInstances);
62+
}));
63+
64+
DataService.list({
65+
group: 'servicecatalog.k8s.io',
66+
resource: 'serviceclasses'
67+
}, context, function(serviceClasses) {
68+
$scope.serviceClasses = serviceClasses.by('metadata.name');
69+
sortServiceInstances();
70+
updateFilter();
71+
});
72+
73+
function updateFilterWarning() {
74+
if (!LabelFilter.getLabelSelector().isEmpty() && _.isEmpty($scope.serviceInstances) && !_.isEmpty($scope.unfilteredServiceInstances)) {
75+
$scope.alerts["all-instances-filtered"] = {
76+
type: "warning",
77+
details: "The active filters are hiding all provisioned services."
78+
};
79+
}
80+
else {
81+
delete $scope.alerts["all-instances-filtered"];
82+
}
83+
}
84+
85+
LabelFilter.onActiveFiltersChanged(function(labelSelector) {
86+
// trigger a digest loop
87+
$scope.$evalAsync(function() {
88+
$scope.serviceInstances = labelSelector.select($scope.unfilteredServiceInstances);
89+
updateFilterWarning();
90+
});
91+
});
92+
93+
$scope.$on('$destroy', function(){
94+
DataService.unwatchAll(watches);
95+
});
96+
97+
}));
98+
});

app/scripts/directives/overview/serviceInstanceRow.js

+7-58
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,10 @@
44
angular.module('openshiftConsole').component('serviceInstanceRow', {
55
controller: [
66
'$filter',
7-
'$uibModal',
8-
'DataService',
7+
'AuthorizationService',
98
'BindingService',
109
'ListRowUtils',
11-
'NotificationsService',
12-
'AuthorizationService',
10+
'ServiceInstancesService',
1311
ServiceInstanceRow
1412
],
1513
controllerAs: 'row',
@@ -22,16 +20,13 @@
2220
});
2321

2422
function ServiceInstanceRow($filter,
25-
$uibModal,
26-
DataService,
23+
AuthorizationService,
2724
BindingService,
2825
ListRowUtils,
29-
NotificationsService,
30-
AuthorizationService) {
26+
ServiceInstancesService) {
3127
var row = this;
3228
_.extend(row, ListRowUtils.ui);
3329

34-
var getErrorDetails = $filter('getErrorDetails');
3530
var serviceInstanceDisplayName = $filter('serviceInstanceDisplayName');
3631

3732
var getDescription = function() {
@@ -95,68 +90,22 @@
9590
if (AuthorizationService.canI({resource: 'serviceinstances', group: 'servicecatalog.k8s.io'}, 'delete')) {
9691
return true;
9792
}
93+
9894
return false;
9995
};
10096

10197
row.closeOverlayPanel = function() {
10298
_.set(row, 'overlay.panelVisible', false);
10399
};
100+
104101
row.showOverlayPanel = function(panelName, state) {
105102
_.set(row, 'overlay.panelVisible', true);
106103
_.set(row, 'overlay.panelName', panelName);
107104
_.set(row, 'overlay.state', state);
108105
};
109106

110107
row.deprovision = function() {
111-
var modalScope = {
112-
alerts: {
113-
deprovision: {
114-
type: 'error',
115-
message: 'Service \'' + row.apiObject.spec.serviceClassName + '\' will be deleted and no longer available.'
116-
}
117-
},
118-
detailsMarkup: 'Delete Service?',
119-
okButtonText: 'Delete',
120-
okButtonClass: 'btn-danger',
121-
cancelButtonText: 'Cancel'
122-
};
123-
// TODO: we probably have to handle bindings in here.
124-
// either:
125-
// - automatically remove the bindings
126-
// - tell the user they must manually unbind before continue
127-
$uibModal.open({
128-
animation: true,
129-
templateUrl: 'views/modals/confirm.html',
130-
controller: 'ConfirmModalController',
131-
resolve: {
132-
modalConfig: function() {
133-
return modalScope;
134-
}
135-
}
136-
})
137-
.result.then(function() {
138-
NotificationsService.hideNotification("deprovision-service-error");
139-
DataService.delete({
140-
group: 'servicecatalog.k8s.io',
141-
resource: 'serviceinstances'
142-
},
143-
row.apiObject.metadata.name,
144-
{ namespace: row.apiObject.metadata.namespace },
145-
{ propagationPolicy: null }) // TODO - remove once this is resolved https://github.com/kubernetes-incubator/service-catalog/issues/942
146-
.then(function() {
147-
NotificationsService.addNotification({
148-
type: "success",
149-
message: "Successfully deleted " + row.apiObject.metadata.name + "."
150-
});
151-
}, function(err) {
152-
NotificationsService.addNotification({
153-
id: "deprovision-service-error",
154-
type: "error",
155-
message: "An error occurred while deleting " + row.apiObject.metadata.name + ".",
156-
details: getErrorDetails(err)
157-
});
158-
});
159-
});
108+
ServiceInstancesService.deprovision(row.apiObject);
160109
};
161110
}
162111
})();

app/scripts/directives/resourceServiceBindings.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ function ResourceServiceBindings($filter, DataService, BindingService, CatalogSe
2727
ctrl.bindableServiceInstances = [];
2828
ctrl.serviceClasses = [];
2929
ctrl.serviceInstances = [];
30-
ctrl.showBindings = CatalogService.SERVICE_CATALOG_ENABLED && enableTechPreviewFeature('pod_presets');
30+
ctrl.showBindings = CatalogService.SERVICE_CATALOG_ENABLED && (_.get(ctrl, 'apiObject.kind') === 'ServiceInstance' || enableTechPreviewFeature('pod_presets'));
3131

3232
var limitWatches = $filter('isIE')() || $filter('isEdge')();
3333
var DEFAULT_POLL_INTERVAL = 60 * 1000; // milliseconds

0 commit comments

Comments
 (0)