Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add delete binding action to provisioned services #1705

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions app/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -337,6 +337,7 @@ <h1>JavaScript Required</h1>
<script src="scripts/directives/buildStatus.js"></script>
<script src="scripts/directives/routeServiceBarChart.js"></script>
<script src="scripts/directives/bindService.js"></script>
<script src="scripts/directives/unbindService.js"></script>
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I prob should rename this file since we no longer call it "unbind"

<script src="scripts/directives/processTemplate.js"></script>
<script src="scripts/directives/processTemplateDialog.js"></script>
<script src="scripts/directives/deployImageDialog.js"></script>
Expand Down
10 changes: 5 additions & 5 deletions app/scripts/directives/bindService.js
Original file line number Diff line number Diff line change
Expand Up @@ -55,15 +55,15 @@
}
};


var deploymentConfigs, deployments, replicationControllers, replicaSets, statefulSets;
var sortApplications = function() {
// Don't waste time sorting on each data load, just sort when we have them all
if (deploymentConfigs && deployments && replicationControllers && replicaSets && statefulSets) {
var apiObjects = deploymentConfigs.concat(deployments)
.concat(replicationControllers)
.concat(replicaSets)
.concat(statefulSets);
var apiObjects = [].concat(deploymentConfigs)
.concat(deployments)
.concat(replicationControllers)
.concat(replicaSets)
.concat(statefulSets);
ctrl.applications = _.sortByAll(apiObjects, ['metadata.name', 'kind']);
ctrl.bindType = ctrl.applications.length ? "application" : "secret-only";
}
Expand Down
10 changes: 2 additions & 8 deletions app/scripts/directives/overview/serviceInstanceRow.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,7 @@
_.extend(row, ListRowUtils.ui);

var getErrorDetails = $filter('getErrorDetails');

var getDisplayName = function() {
var serviceClassName = row.apiObject.spec.serviceClassName;
var instanceName = row.apiObject.metadata.name;
var serviceClassDisplayName = _.get(row, ['state','serviceClasses', serviceClassName, 'externalMetadata', 'displayName']);
return serviceClassDisplayName || serviceClassName || instanceName;
};
var serviceInstanceDisplayName = $filter('serviceInstanceDisplayName');

var getDescription = function() {
var serviceClassName = row.apiObject.spec.serviceClassName;
Expand All @@ -45,7 +39,7 @@

row.$doCheck = function() {
row.notifications = ListRowUtils.getNotifications(row.apiObject, row.state);
row.displayName = getDisplayName();
row.displayName = serviceInstanceDisplayName(row.apiObject, row.serviceClasses);
row.description = getDescription();
};

Expand Down
106 changes: 106 additions & 0 deletions app/scripts/directives/unbindService.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
'use strict';

(function() {

angular.module('openshiftConsole').component('unbindService', {
controller: [
'$scope',
'$filter',
'DataService',
UnbindService
],
controllerAs: 'ctrl',
bindings: {
target: '<',
bindings: '<',
applicationsByBinding: '<',
onClose: '<'
},
templateUrl: 'views/directives/unbind-service.html'
});

function UnbindService($scope, $filter, DataService) {
var ctrl = this;
var validityWatcher;
var context;
var serviceInstanceDisplayName = $filter('serviceInstanceDisplayName');

var unbindService = function() {
DataService.delete({
group: 'servicecatalog.k8s.io',
resource: 'bindings'
}, ctrl.selectedBinding, context).then(_.noop, function(err) {
ctrl.error = err;
});
};

var setupValidator = function() {
var firstStep = _.first(ctrl.steps);
firstStep.valid = false;
// TODO: auto-select if one option is kludgy. will follow-on a fix
// if(_.size(ctrl.bindings) === 1) {
// firstStep.valid = true;
// ctrl.selectedBinding = _.first(ctrl.bindings);
// } else {
validityWatcher = $scope.$watch("ctrl.selectedBinding", function(selectedBinding) {
firstStep.valid = !!selectedBinding;
});
// }
};

var tearDownValidator = function() {
if(validityWatcher) {
validityWatcher();
validityWatcher = undefined;
}
};

var showDeleteForm = function() {
ctrl.nextTitle = 'Delete';
setupValidator();
};

var showResults = function() {
ctrl.nextTitle = 'Close';
ctrl.wizardComplete = true;
unbindService();
tearDownValidator();
};

ctrl.$onInit = function() {
var formStepLabel = (ctrl.target.kind === 'Instance') ? 'Applications' : 'Services';
ctrl.displayName = serviceInstanceDisplayName(ctrl.target);
ctrl.steps = [{
id: 'deleteForm',
label: formStepLabel,
view: 'views/directives/bind-service/delete-binding-select-form.html',
onShow: showDeleteForm
}, {
id: 'results',
label: 'Results',
view: 'views/directives/bind-service/delete-binding-result.html',
onShow: showResults
}];

context = {
namespace: _.get(ctrl.target, 'metadata.namespace')
};
};

ctrl.appsForBinding = function(bindingName) {
return _.get(ctrl.applicationsByBinding, bindingName);
};

ctrl.closeWizard = function() {
if (_.isFunction(ctrl.onClose)) {
ctrl.onClose();
}
};

ctrl.$onDestroy = function() {
tearDownValidator();
};

}

})();
13 changes: 13 additions & 0 deletions app/scripts/filters/resources.js
Original file line number Diff line number Diff line change
Expand Up @@ -1315,4 +1315,17 @@ angular.module('openshiftConsole')
var alternateBackends = _.get(route, 'spec.alternateBackends', []);
return !_.isEmpty(alternateBackends);
};
})
// .filter('serviceClassDisplayName', function() {
// return function(serviceClass) {
// TODO: this filter may also be useful.
// };
// })
.filter('serviceInstanceDisplayName', function() {
return function(instance, serviceClasses) {
var serviceClassName = instance.spec.serviceClassName;
var instanceName = instance.metadata.name;
var serviceClassDisplayName = _.get(serviceClasses, [serviceClassName, 'externalMetadata', 'displayName']);
return serviceClassDisplayName || serviceClassName || instanceName;
};
});
32 changes: 32 additions & 0 deletions app/views/directives/bind-service/delete-binding-result.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<div>
<div ng-if="!ctrl.error">
<h3 class="mar-top-none">
Binding for the following has been deleted:
</h3>

<div
ng-if="ctrl.appsForBinding(ctrl.selectedBinding)"
ng-repeat="appForBinding in ctrl.appsForBinding(ctrl.selectedBinding)">
{{appForBinding.metadata.name}} <small class="text-muted">&ndash; {{ appForBinding.kind | humanizeKind : true}}</small>
</div>
<div ng-if="!(ctrl.appsForBinding(ctrl.selectedBinding))">
<!-- TODO: selected a secret name in the form, but see a binding name in the result. -->
{{ctrl.selectedBinding}} <small class="text-muted">&ndash; Binding</small>
</div>

<p class="mar-top-lg">
<span class="pficon pficon-info"></span> You will need to redeploy your pods for this to take effect.
</p>
</div>
<div ng-if="ctrl.error">
<div class="title">Deletion of Binding Failed <span class="fa fa-times text-danger"></span></div>
<div class="sub-title">
<span ng-if="ctrl.error.data.message">
{{ctrl.error.data.message | upperFirst}}
</span>
<span ng-if="!ctrl.error.data.message">
An error occurred deleting the binding.
</span>
</div>
</div>
</div>
24 changes: 24 additions & 0 deletions app/views/directives/bind-service/delete-binding-select-form.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<h3 class="mar-top-none">
Select a binding to delete from <strong>{{ctrl.displayName}}</strong>
</h3>
<form name="ctrl.bindingSelection" class="mar-bottom-lg">
<fieldset ng-disabled="ctrl.isDisabled">
<div ng-repeat="binding in ctrl.bindings" class="radio">
<label>
<input
type="radio"
ng-model="ctrl.selectedBinding"
value="{{binding.metadata.name}}">
<div
ng-if="ctrl.appsForBinding(binding.metadata.name)"
ng-repeat="appForBinding in ctrl.appsForBinding(binding.metadata.name)">
{{appForBinding.metadata.name}} <small class="text-muted">&ndash; {{ appForBinding.kind | humanizeKind : true}}</small>
</div>
<div ng-if="!(ctrl.appsForBinding(binding.metadata.name))">
{{binding.spec.secretName}} <small class="text-muted">&ndash; Secret</small>
</div>

</label>
</div>
</fieldset>
</form>
29 changes: 29 additions & 0 deletions app/views/directives/unbind-service.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<div class="bind-service-wizard unbind-service">
<div
pf-wizard
hide-header="true"
hide-sidebar="true"
hide-back-button="true"
step-class="bind-service-wizard-step"
wizard-ready="ctrl.wizardReady"
next-title="ctrl.nextTitle"
on-finish="ctrl.closeWizard()"
on-cancel="ctrl.closeWizard()"
wizard-done="ctrl.wizardComplete"
class="pf-wizard-no-back">
<div
pf-wizard-step
ng-repeat="step in ctrl.steps track by $index"
step-title="{{step.label}}"
next-enabled="step.valid"
on-show="step.onShow"
step-id="{{step.id}}"
step-priority="{{$index}}">
<div class="wizard-pf-main-inner-shadow-covers">
<div class="bind-service-config">
<div ng-include="step.view" class="wizard-pf-main-form-contents"></div>
</div>
</div>
</div>
</div>
</div>
5 changes: 4 additions & 1 deletion app/views/overview/_list-row-actions.html
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,12 @@
</li>
<!-- FIXME: Can't enable canI checks on svc cat resources until we have aggregation
<li ng-if="(row.state.serviceInstances | hashSize) > 0 && {resource: 'bindings', group: 'servicecatalog.k8s.io'} | canI : 'create'" role="menuitem"> -->
<li ng-if="('pod_presets' | enableTechPreviewFeature) && row.state.bindableServiceInstances.length" role="menuitem">
<li ng-if-start="('pod_presets' | enableTechPreviewFeature) && row.state.bindableServiceInstances.length" role="menuitem">
<a href="" ng-click="row.showOverlayPanel('bindService', {target: row.apiObject})">Create Binding</a>
</li>
<li ng-if-end role="menuitem">
<a href="" ng-click="row.showOverlayPanel('unbindService', {target: row.apiObject})">Delete Binding</a>
</li>
<li ng-if="row.current && ('deploymentconfigs/log' | canI : 'get')" role="menuitem">
<a ng-href="{{row.current | navigateResourceURL}}?tab=logs">View Logs</a>
</li>
Expand Down
6 changes: 6 additions & 0 deletions app/views/overview/_list-row.html
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,10 @@
<bind-service target="row.overlay.state.target"
on-close="row.closeOverlayPanel"></bind-service>
</div>
<div ng-if="row.overlay.panelName === 'unbindService'">
<unbind-service
target="row.overlay.state.target"
bindings="row.bindings"
on-close="row.closeOverlayPanel"></unbind-service>
</div>
</overlay-panel>
12 changes: 11 additions & 1 deletion app/views/overview/_service-instance-row.html
Original file line number Diff line number Diff line change
Expand Up @@ -52,9 +52,12 @@ <h3>
uib-dropdown-toggle
class="actions-dropdown-kebab"><i class="fa fa-ellipsis-v"></i><span class="sr-only">Actions</span></a>
<ul class="dropdown-menu dropdown-menu-right" uib-dropdown-menu role="menu">
<li role="menuitem" ng-if="row.isBindable">
<li role="menuitem" ng-if="('pod_presets' | enableTechPreviewFeature) && row.isBindable">
<a href="" ng-click="row.showOverlayPanel('bindService', {target: row.apiObject})">Create Binding</a>
</li>
<li role="menuitem" ng-if="('pod_presets' | enableTechPreviewFeature) && row.bindings.length">
<a href="" ng-click="row.showOverlayPanel('unbindService', {target: row.apiObject})">Delete Binding</a>
</li>
<li role="menuitem">
<a href="" ng-click="row.deprovision()" role="button">Deprovision</a>
</li>
Expand Down Expand Up @@ -148,4 +151,11 @@ <h3>
<bind-service target="row.overlay.state.target"
on-close="row.closeOverlayPanel"></bind-service>
</div>
<div ng-if="row.overlay.panelName === 'unbindService'">
<unbind-service
target="row.overlay.state.target"
bindings="row.bindings"
applications-by-binding="row.state.applicationsByBinding"
on-close="row.closeOverlayPanel"></unbind-service>
</div>
</overlay-panel>
Loading