Skip to content

Commit

Permalink
Updates for Service Instance & Bindings
Browse files Browse the repository at this point in the history
Updates for service instances. Prep to allow updates
to chosen parameters for instance and bindings.
  • Loading branch information
cdcabrera committed Aug 24, 2017
1 parent c9a5d1a commit 99e5d5a
Show file tree
Hide file tree
Showing 17 changed files with 931 additions and 80 deletions.
2 changes: 2 additions & 0 deletions app/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -255,6 +255,8 @@ <h1>JavaScript Required</h1>
<script src="scripts/controllers/statefulSet.js"></script>
<script src="scripts/controllers/services.js"></script>
<script src="scripts/controllers/service.js"></script>
<script src="scripts/controllers/serviceInstances.js"></script>
<script src="scripts/controllers/serviceInstance.js"></script>
<script src="scripts/controllers/secrets.js"></script>
<script src="scripts/controllers/secret.js"></script>
<script src="scripts/controllers/createSecret.js"></script>
Expand Down
10 changes: 10 additions & 0 deletions app/scripts/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -271,6 +271,16 @@ angular
controller: 'ServiceController',
reloadOnSearch: false
})
.when('/project/:project/browse/service-instances', {
templateUrl: 'views/service-instances.html',
controller: 'ServiceInstancesController',
reloadOnSearch: false
})
.when('/project/:project/browse/service-instances/:instance', {
templateUrl: 'views/browse/service-instance.html',
controller: 'ServiceInstanceController',
reloadOnSearch: false
})
.when('/project/:project/browse/storage', {
templateUrl: 'views/storage.html',
controller: 'StorageController',
Expand Down
17 changes: 17 additions & 0 deletions app/scripts/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,23 @@ angular.extend(window.OPENSHIFT_CONSTANTS, {
prefixes: [
"/browse/routes/"
]
},
{
label: "Provisioned Services",
href: "/browse/service-instances",
prefixes: [
"/browse/service-instances/"
],
isValid: function(){
return _.get(window.OPENSHIFT_CONSTANTS, 'ENABLE_TECH_PREVIEW_FEATURE.service_catalog_landing_page');
},
canI: {
resource: {
group: 'servicecatalog.k8s.io',
resource: 'instances'
},
verb: 'list'
}
}
]
}
Expand Down
104 changes: 104 additions & 0 deletions app/scripts/controllers/serviceInstance.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
'use strict';

angular.module('openshiftConsole')
.controller('ServiceInstanceController', function ($scope,
$filter,
$routeParams,
DataService,
ProjectsService) {
$scope.alerts = {};
//$scope.displayName = null;
$scope.projectName = $routeParams.project;
$scope.serviceInstance = null;
$scope.serviceClass = null;
$scope.serviceClasses = {};

$scope.breadcrumbs = [
{
title: "Provisioned Services",
link: "project/" + $routeParams.project + "/browse/service-instances"
},
{
title: $routeParams.instance
}
];

var watches = [];

/*var setDisplayName = function() {
if(!$scope.serviceInstance || !$scope.serviceClasses) {
return;
}
$scope.displayName = $filter('serviceInstanceDisplayName')($scope.serviceInstance, $scope.serviceClasses);
};*/

var updateServiceClassMetadata = function() {
if(!$scope.serviceInstance || !$scope.serviceClasses) {
return;
}

var serviceClassName = _.get($scope.serviceInstance.spec, 'serviceClassName');
$scope.serviceClass = _.get($scope.serviceClasses, [serviceClassName]);
$scope.plan = _.find(_.get($scope.serviceClass, 'plans'), {name: 'default'});
};

var serviceResolved = function(service, action) {
$scope.loaded = true;
$scope.serviceInstance = service;

if (action === "DELETED") {
$scope.alerts["deleted"] = {
type: "warning",
message: "This provisioned service has been deleted."
};
}

//setDisplayName();
updateServiceClassMetadata();
};

ProjectsService
.get($routeParams.project)
.then(_.spread(function(project, context) {
$scope.project = project;
$scope.projectContext = context;

DataService
.get({
group: 'servicecatalog.k8s.io',
resource: 'instances'
}, $routeParams.instance, context, { errorNotification: false })
.then(function(service) {

serviceResolved(service);

watches.push(DataService.watchObject({
group: 'servicecatalog.k8s.io',
resource: 'instances'
}, $routeParams.instance, context, serviceResolved));

}, function(error) {
$scope.loaded = true;
$scope.alerts["load"] = {
type: "error",
message: "The service details could not be loaded.",
details: $filter('getErrorDetails')(error)
};
});

DataService.list({
group: 'servicecatalog.k8s.io',
resource: 'serviceclasses'
}, context, function(serviceClasses) {
$scope.serviceClasses = serviceClasses.by('metadata.name');
//setDisplayName();
updateServiceClassMetadata();
});

$scope.$on('$destroy', function(){
DataService.unwatchAll(watches);
});

}));
});
185 changes: 185 additions & 0 deletions app/scripts/controllers/serviceInstances.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,185 @@
'use strict';

angular.module('openshiftConsole')
.controller('ServiceInstancesController', function ($scope,
$filter,
$routeParams,
APIService,
BindingService,
Constants,
DataService,
LabelFilter,
Logger,
ProjectsService) {
$scope.alerts = {};
$scope.applicationsByBinding = {};
$scope.bindings = {};
$scope.bindableServiceInstances = {};
//$scope.bindingsByApplicationUID = {};
$scope.bindingsByInstanceRef = {};
$scope.emptyMessage = "Loading...";
$scope.labelSuggestions = {};
$scope.projectName = $routeParams.project;
$scope.serviceClasses = {};
$scope.serviceInstances = {};
$scope.unfilteredServiceInstances = {};

var watches = [];

var updateFilter = function() {
$scope.serviceInstances = LabelFilter.getLabelSelector().select($scope.unfilteredServiceInstances);
};

var sortServiceInstances = function() {
$scope.bindableServiceInstances = BindingService.filterBindableServiceInstances($scope.unfilteredServiceInstances, $scope.serviceClasses);
$scope.unfilteredServiceInstances = BindingService.sortServiceInstances($scope.unfilteredServiceInstances, $scope.serviceClasses);
};

var groupBindings = function() {
// Build two maps:
// - Bindings by the UID of the target object
// - API objects by binding name
/*
state.bindingsByApplicationUID = {};
state.applicationsByBinding = {};
//state.deleteableBindingsByApplicationUID = {};
// If there are no bindings, nothing to do.
if (_.isEmpty(state.bindings)) {
return;
}
// All objects that can be a target for bindings.
var objectsByKind = [
overview.deployments,
overview.deploymentConfigs,
overview.vanillaReplicationControllers,
overview.vanillaReplicaSets,
overview.statefulSets
];
// Make sure all the binding targets have loaded first.
if (_.some(objectsByKind, function(collection) { return !collection; })) {
return;
}
// Build a map of pod preset selectors by binding name.
var podPresetSelectors = {};
_.each(state.bindings, function(binding) {
var podPresetSelector = _.get(binding, 'spec.alphaPodPresetTemplate.selector');
if (podPresetSelector) {
podPresetSelectors[binding.metadata.name] = new LabelSelector(podPresetSelector);
}
});
_.each(objectsByKind, function(collection) {
_.each(collection, function(apiObject) {
// Key by UID since name is not unique across different kinds.
var applicationUID = getUID(apiObject);
// Create a selector for the potential binding target to check if the
// pod preset covers the selector.
var applicationSelector = new LabelSelector(_.get(apiObject, 'spec.selector'));
state.bindingsByApplicationUID[applicationUID] = [];
state.deleteableBindingsByApplicationUID[applicationUID] = [];
// Look at each pod preset selector to see if it covers this API object selector.
_.each(podPresetSelectors, function(podPresetSelector, bindingName) {
if (podPresetSelector.covers(applicationSelector)) {
// Keep a map of the target UID to the binding and the binding to
// the target. We want to show bindings both in the "application"
// object rows and the service instance rows.
state.bindingsByApplicationUID[applicationUID].push(state.bindings[bindingName]);
if (!_.get(state.bindings[bindingName], 'metadata.deletionTimestamp')) {
state.deleteableBindingsByApplicationUID[applicationUID].push(state.bindings[bindingName]);
}
state.applicationsByBinding[bindingName] = state.applicationsByBinding[bindingName] || [];
state.applicationsByBinding[bindingName].push(apiObject);
}
});
});
});
$scope.bindingsByInstanceRef = _.reduce(state.bindingsByInstanceRef, function(result, bindingList, key) {
result[key] = _.sortBy(bindingList, function(binding) {
var apps = _.get(state.applicationsByBinding, [binding.metadata.name]);
var firstName = _.get(_.head(apps), ['metadata', 'name']);
return firstName || binding.metadata.name;
});
return result;
}, {});*/
};

ProjectsService
.get($routeParams.project)
.then(_.spread(function(project, context) {
$scope.project = project;
$scope.projectContext = context;

watches.push(DataService.watch({
group: 'servicecatalog.k8s.io',
resource: 'bindings'
}, context, function(bindings) {
$scope.bindings = bindings.by('metadata.name');
$scope.bindingsByInstanceRef = _.groupBy($scope.bindings, 'spec.instanceRef.name');
groupBindings();
//refreshSecrets(context);
}));

watches.push(DataService.watch({
group: 'servicecatalog.k8s.io',
resource: 'instances'
}, context, function(serviceInstances) {
$scope.emptyMessage = "No provisioned services to show";
$scope.unfilteredServiceInstances = serviceInstances.by('metadata.name');

//_.each($scope.unfilteredServiceInstances, function (instance) {
// var notifications = ResourceAlertsService.getServiceInstanceAlerts(instance);
// setNotifications(instance, notifications);
//});

sortServiceInstances();
updateFilter();
updateFilterWarning();

LabelFilter.addLabelSuggestionsFromResources($scope.unfilteredServiceInstances, $scope.labelSuggestions);
LabelFilter.setLabelSuggestions($scope.labelSuggestions);

Logger.log("provisioned services (subscribe)", $scope.unfilteredServiceInstances);
}));

DataService.list({
group: 'servicecatalog.k8s.io',
resource: 'serviceclasses'
}, context, function(serviceClasses) {
$scope.serviceClasses = serviceClasses.by('metadata.name');
sortServiceInstances();
updateFilter();
});

function updateFilterWarning() {
if (!LabelFilter.getLabelSelector().isEmpty() && _.isEmpty($scope.serviceInstances) && !_.isEmpty($scope.unfilteredServiceInstances)) {
$scope.alerts["all-instances-filtered"] = {
type: "warning",
details: "The active filters are hiding all provisioned services."
};
}
else {
delete $scope.alerts["all-instances-filtered"];
}
}

LabelFilter.onActiveFiltersChanged(function(labelSelector) {
// trigger a digest loop
$scope.$apply(function() {
$scope.serviceInstances = labelSelector.select($scope.unfilteredServiceInstances);
updateFilterWarning();
});
});

$scope.$on('$destroy', function(){
DataService.unwatchAll(watches);
});

}));
});
1 change: 1 addition & 0 deletions app/scripts/directives/overview/serviceBinding.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
bindings: {
namespace: '<',
binding: '<',
refApiObject: '<?',
serviceClasses: '<',
serviceInstances: '<'
},
Expand Down
7 changes: 5 additions & 2 deletions app/scripts/directives/resourceServiceBindings.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,11 @@ function ResourceServiceBindings($filter, DataService, BindingService, CatalogSe
return;
}

// Get only those bindings applicable to the resource
ctrl.bindings = BindingService.getBindingsForResource(ctrl.bindings, ctrl.apiObject);
if (_.get(ctrl.apiObject, 'kind') === 'Instance') {
ctrl.bindings = _.filter(ctrl.bindings, ['spec.instanceRef.name', _.get(ctrl.apiObject, 'metadata.name')]);
} else {
ctrl.bindings = BindingService.getBindingsForResource(ctrl.bindings, ctrl.apiObject);
}
};

var sortServiceInstances = function() {
Expand Down
3 changes: 3 additions & 0 deletions app/scripts/filters/canI.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@ angular
'imageStreams': [
{group: '', resource: 'imagestreams', verbs: ['update', 'delete']}
],
'instances': [
{group: 'servicecatalog.k8s.io', resource: 'instances', verbs: ['update', 'create', 'delete']}
],
'persistentVolumeClaims': [
{group: '', resource: 'persistentvolumeclaims', verbs: ['update', 'delete']}
],
Expand Down
16 changes: 16 additions & 0 deletions app/scripts/filters/resources.js
Original file line number Diff line number Diff line change
Expand Up @@ -1328,4 +1328,20 @@ angular.module('openshiftConsole')
var serviceClassDisplayName = _.get(serviceClasses, [serviceClassName, 'externalMetadata', 'displayName']);
return serviceClassDisplayName || serviceClassName || instanceName;
};
})
.filter('serviceInstanceStatus', function(isServiceInstanceReadyFilter) {
return function(instance) {
var status = 'Pending';

if (isServiceInstanceReadyFilter(instance)) {
status = 'Succeeded';
}

return status;
};
})
.filter('serviceInstanceMessage', function(statusConditionFilter) {
return function(instance) {
return _.get(statusConditionFilter(instance, 'Ready'), 'message');
};
});
Loading

0 comments on commit 99e5d5a

Please sign in to comment.