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

Delete bindings when deleting a service instance #2150

Merged
merged 1 commit into from
Sep 26, 2017
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
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