Skip to content

Commit

Permalink
Delete bindings when deleting a service instance
Browse files Browse the repository at this point in the history
  • Loading branch information
jeff-phillips-18 committed Sep 26, 2017
1 parent b92abe5 commit 1056510
Show file tree
Hide file tree
Showing 8 changed files with 184 additions and 90 deletions.
2 changes: 1 addition & 1 deletion app/scripts/directives/overview/serviceInstanceRow.js
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@
};

row.deprovision = function() {
ServiceInstancesService.deprovision(row.apiObject);
ServiceInstancesService.deprovision(row.apiObject, row.deleteableBindings);
};
}
})();
136 changes: 94 additions & 42 deletions app/scripts/services/serviceInstances.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,65 +2,117 @@

angular.module("openshiftConsole")
.factory("ServiceInstancesService", function($filter,
$q,
$uibModal,
APIService,
BindingService,
CatalogService,
DataService,
Logger,
NotificationsService) {
var getBindingsIfNecessary = function(apiObject, bindings) {
if (angular.isDefined(bindings)) {
return $q.when(bindings);
}

function deprovision(apiObject) {
var getErrorDetails = $filter('getErrorDetails');
var modalScope = {
alerts: {
deprovision: {
type: 'error',
message: 'Service \'' + apiObject.spec.serviceClassName + '\' will be deleted and no longer available.'
var context = {namespace: apiObject.metadata.namespace};
var resource = APIService.getPreferredVersion('serviceinstancecredentials');

return DataService.list(resource, context).then(function(serviceBindings) {
bindings = serviceBindings.by('metadata.name');
return BindingService.getBindingsForResource(bindings, apiObject);
});
};

var deprovisionInstance = function(apiObject) {
var context = {namespace: apiObject.metadata.namespace};
var resource = APIService.getPreferredVersion('serviceinstances');

NotificationsService.hideNotification("deprovision-service-error");

// TODO - remove once this is resolved https://github.com/kubernetes-incubator/service-catalog/issues/942
var opts = {
propagationPolicy: null
};

return DataService.delete(resource, apiObject.metadata.name, context, opts).then(function() {
NotificationsService.addNotification({
type: "success",
message: "Provisioned service '" + apiObject.metadata.name + "' was marked for deletion."
});
}, function(err) {
NotificationsService.addNotification({
id: "deprovision-service-error",
type: "error",
message: "An error occurred while deleting provisioned service " + apiObject.metadata.name + ".",
details: $filter('getErrorDetails')(err)
});
Logger("An error occurred while deleting provisioned service " + apiObject.metadata.name + ".", err);
});
};

var deprovisionBindings = function(apiObject, bindings) {
if (!CatalogService.SERVICE_CATALOG_ENABLED) {
return;
}

var context = {namespace: apiObject.metadata.namespace};
var resource = APIService.getPreferredVersion('serviceinstancecredentials');
getBindingsIfNecessary(apiObject, bindings).then(function(serviceBindings) {
_.each(serviceBindings, function (binding) {
if (!binding.metadata.deletionTimestamp) {
return;
}
},
detailsMarkup: 'Delete Service?',

DataService.delete(resource, binding.metadata.name, context)
.then(function () {
NotificationsService.addNotification({
type: "success",
message: 'Binding ' + binding.metadata.name + "' was marked for deletion."
});
})
.catch(function (err) {
NotificationsService.addNotification({
type: "error",
message: 'Binding ' + binding.metadata.name + "' could not be deleted.",
details: $filter('getErrorDetails')(err)
});
Logger.error('Binding ' + binding.metadata.name + "' could not be deleted.", err);
});
});
});
};

var deprovision = function (apiObject, bindings) {
var modalInstance;

var modalScope = {
kind: apiObject.kind,
displayName: apiObject.metadata.name,
okButtonText: 'Delete',
okButtonClass: 'btn-danger',
cancelButtonText: 'Cancel'
cancelButtonText: 'Cancel',
delete: function() {
modalInstance.close('delete');
}
};

// TODO: we probably have to handle bindings in here.
// either:
// - automatically remove the bindings
// - tell the user they must manually unbind before continue
return $uibModal.open({
modalInstance = $uibModal.open({
animation: true,
templateUrl: 'views/modals/confirm.html',
templateUrl: 'views/modals/delete-resource.html',
controller: 'ConfirmModalController',
resolve: {
modalConfig: function() {
return modalScope;
}
}
})
.result.then(function() {
NotificationsService.hideNotification("deprovision-service-error");

return DataService.delete({
group: 'servicecatalog.k8s.io',
resource: 'serviceinstances'
},
apiObject.metadata.name,
{ namespace: apiObject.metadata.namespace },
{ propagationPolicy: null
}) // TODO - remove once this is resolved https://github.com/kubernetes-incubator/service-catalog/issues/942
.then(function() {
NotificationsService.addNotification({
type: "success",
message: "Successfully deleted provisioned service " + apiObject.metadata.name + "."
});
}, function(err) {
NotificationsService.addNotification({
id: "deprovision-service-error",
type: "error",
message: "An error occurred while deleting provisioned service " + apiObject.metadata.name + ".",
details: getErrorDetails(err)
});
});
});
}

return modalInstance.result.then(function() {
deprovisionBindings(apiObject, bindings);
deprovisionInstance(apiObject);
});
};

return {
deprovision: deprovision
Expand Down
2 changes: 1 addition & 1 deletion app/views/directives/_service-binding.html
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ <h3>
<status-icon status="'Pending'"></status-icon>Pending
</div>
</div>
<div class="service-binding-actions" ng-if="!ctrl.binding.metadata.deletionTimestamp">
<div class="service-binding-actions" ng-if="!$ctrl.binding.metadata.deletionTimestamp">
<delete-link
ng-if="({resource: 'serviceinstancecredentials', group: 'servicecatalog.k8s.io'} | canI : 'delete')"
kind="ServiceInstanceCredential"
Expand Down
8 changes: 5 additions & 3 deletions app/views/directives/resource-service-bindings.html
Original file line number Diff line number Diff line change
Expand Up @@ -8,19 +8,21 @@ <h3>Bindings</h3>
service-classes="$ctrl.serviceClasses"
service-instances="$ctrl.serviceInstances">
</service-binding>
<div ng-if="($ctrl.bindableServiceInstances | size) && ({resource: 'serviceinstancecredentials', group: 'servicecatalog.k8s.io'} | canI : 'create')">
<div ng-if="(($ctrl.apiObject.kind === 'ServiceInstance') || ($ctrl.bindableServiceInstances | size)) &&
({resource: 'serviceinstancecredentials', group: 'servicecatalog.k8s.io'} | canI : 'create') &&
!$ctrl.apiObject.metadata.deletionTimestamp">
<a href="" ng-click="$ctrl.createBinding()" role="button">
<span class="pficon pficon-add-circle-o" aria-hidden="true"></span>
Create Binding
</a>
</div>
<div ng-if="!($ctrl.bindableServiceInstances | size)">
<div ng-if="!$ctrl.apiObject.metadata.deletionTimestamp && ($ctrl.apiObject.kind !== 'ServiceInstance') && !($ctrl.bindableServiceInstances | size)">
<span>You must have a bindable service in your namespace in order to create bindings.</span>
<div>
<a href="./">Browse Catalog</a>
</div>
</div>
<div ng-if="!($ctrl.bindings | size) && ($ctrl.bindableServiceInstances | size) && !({resource: 'serviceinstancecredentials', group: 'servicecatalog.k8s.io'} | canI : 'create')">
<div ng-if="($ctrl.apiObject.kind !== 'ServiceInstance') && !($ctrl.bindings | size) && ($ctrl.bindableServiceInstances | size) && !({resource: 'serviceinstancecredentials', group: 'servicecatalog.k8s.io'} | canI : 'create')">
<span>There are no service bindings.</span>
</div>
</div>
Expand Down
4 changes: 4 additions & 0 deletions app/views/modals/delete-resource.html
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@ <h1>Are you sure you want to delete the {{typeDisplayName || (kind | humanizeKin
This will delete the {{typeDisplayName || (kind | humanizeKind)}} and any running pods.
</span>

<span ng-if="kind === 'ServiceInstance'">
{{displayName ? displayName : resourceName}} and its data will no longer be available to your applications.
</span>

<span ng-if="isProject">
This will <strong>delete all resources</strong> associated with the
project {{displayName ? displayName : resourceName}}.
Expand Down
4 changes: 2 additions & 2 deletions app/views/overview/_service-bindings.html
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,13 @@
service-instances="$ctrl.serviceInstances"
secrets="$ctrl.secrets">
</service-binding>
<div ng-if="($ctrl.bindableServiceInstances | size) && ({resource: 'serviceinstancecredentials', group: 'servicecatalog.k8s.io'} | canI : 'create')">
<div ng-if="!$ctrl.refApiObject.metadata.deletionTimestamp && (($ctrl.refApiObject.kind === 'ServiceInstance') || ($ctrl.bindableServiceInstances | size)) && ({resource: 'serviceinstancecredentials', group: 'servicecatalog.k8s.io'} | canI : 'create')">
<a href="" ng-click="$ctrl.createBinding()" role="button">
<span class="pficon pficon-add-circle-o" aria-hidden="true"></span>
Create Binding
</a>
</div>
<div ng-if="!($ctrl.bindableServiceInstances | size)">
<div ng-if="($ctrl.refApiObject.kind !== 'ServiceInstance') && !($ctrl.bindableServiceInstances | size)">
<span>You must have a bindable service in your namespace in order to create bindings.</span>
<div>
<a href="./">Browse Catalog</a>
Expand Down
101 changes: 66 additions & 35 deletions dist/scripts/scripts.js
Original file line number Diff line number Diff line change
Expand Up @@ -4278,51 +4278,82 @@ controller: !0
});
}
};
}), angular.module("openshiftConsole").factory("ServiceInstancesService", [ "$filter", "$uibModal", "DataService", "NotificationsService", function(e, t, n, a) {
return {
deprovision: function(r) {
var o = e("getErrorDetails"), i = {
alerts: {
deprovision: {
}), angular.module("openshiftConsole").factory("ServiceInstancesService", [ "$filter", "$q", "$uibModal", "APIService", "BindingService", "CatalogService", "DataService", "Logger", "NotificationsService", function(e, t, n, a, r, o, i, s, c) {
var l = function(e, n) {
if (angular.isDefined(n)) return t.when(n);
var o = {
namespace: e.metadata.namespace
}, s = a.getPreferredVersion("serviceinstancecredentials");
return i.list(s, o).then(function(t) {
return n = t.by("metadata.name"), r.getBindingsForResource(n, e);
});
}, u = function(t) {
var n = {
namespace: t.metadata.namespace
}, r = a.getPreferredVersion("serviceinstances");
c.hideNotification("deprovision-service-error");
var o = {
propagationPolicy: null
};
return i.delete(r, t.metadata.name, n, o).then(function() {
c.addNotification({
type: "success",
message: "Provisioned service '" + t.metadata.name + "' was marked for deletion."
});
}, function(n) {
c.addNotification({
id: "deprovision-service-error",
type: "error",
message: "An error occurred while deleting provisioned service " + t.metadata.name + ".",
details: e("getErrorDetails")(n)
}), s("An error occurred while deleting provisioned service " + t.metadata.name + ".", n);
});
}, d = function(t, n) {
if (o.SERVICE_CATALOG_ENABLED) {
var r = {
namespace: t.metadata.namespace
}, u = a.getPreferredVersion("serviceinstancecredentials");
l(t, n).then(function(t) {
_.each(t, function(t) {
t.metadata.deletionTimestamp && i.delete(u, t.metadata.name, r).then(function() {
c.addNotification({
type: "success",
message: "Binding " + t.metadata.name + "' was marked for deletion."
});
}).catch(function(n) {
c.addNotification({
type: "error",
message: "Service '" + r.spec.serviceClassName + "' will be deleted and no longer available."
message: "Binding " + t.metadata.name + "' could not be deleted.",
details: e("getErrorDetails")(n)
}), s.error("Binding " + t.metadata.name + "' could not be deleted.", n);
});
});
});
}
},
detailsMarkup: "Delete Service?",
};
return {
deprovision: function(e, t) {
var a, r = {
kind: e.kind,
displayName: e.metadata.name,
okButtonText: "Delete",
okButtonClass: "btn-danger",
cancelButtonText: "Cancel"
cancelButtonText: "Cancel",
delete: function() {
a.close("delete");
}
};
return t.open({
return (a = n.open({
animation: !0,
templateUrl: "views/modals/confirm.html",
templateUrl: "views/modals/delete-resource.html",
controller: "ConfirmModalController",
resolve: {
modalConfig: function() {
return i;
return r;
}
}
}).result.then(function() {
return a.hideNotification("deprovision-service-error"), n.delete({
group: "servicecatalog.k8s.io",
resource: "serviceinstances"
}, r.metadata.name, {
namespace: r.metadata.namespace
}, {
propagationPolicy: null
}).then(function() {
a.addNotification({
type: "success",
message: "Successfully deleted provisioned service " + r.metadata.name + "."
});
}, function(e) {
a.addNotification({
id: "deprovision-service-error",
type: "error",
message: "An error occurred while deleting provisioned service " + r.metadata.name + ".",
details: o(e)
});
});
})).result.then(function() {
d(e, t), u(e);
});
}
};
Expand Down Expand Up @@ -13566,7 +13597,7 @@ _.set(o, "overlay.panelVisible", !1);
}, o.showOverlayPanel = function(e, t) {
_.set(o, "overlay.panelVisible", !0), _.set(o, "overlay.panelName", e), _.set(o, "overlay.state", t);
}, o.deprovision = function() {
r.deprovision(o.apiObject);
r.deprovision(o.apiObject, o.deleteableBindings);
};
} ],
controllerAs: "row",
Expand Down
Loading

0 comments on commit 1056510

Please sign in to comment.