Commit 0f4d8365 by Samuel Padgett

Add requester-username parameter when needed on bind

Add the required `template.openshift.io/requester-username` parameter
if needed for the template broker on bind requests.
parent 5d715783
......@@ -998,29 +998,63 @@ angular.module('openshiftCommonServices')
;'use strict';
angular.module("openshiftCommonServices")
.service("BindingService", function($filter, $q, DataService, DNS1123_SUBDOMAIN_VALIDATION){
.service("BindingService",
function($filter,
$q,
AuthService,
DataService,
DNS1123_SUBDOMAIN_VALIDATION) {
var bindingResource = {
group: 'servicecatalog.k8s.io',
resource: 'bindings'
};
var makeBinding = function (serviceToBind, appToBind) {
var getServiceClassForInstance = function(serviceInstance, serviceClasses) {
var serviceClassName = _.get(serviceInstance, 'spec.serviceClassName');
return _.get(serviceClasses, [serviceClassName]);
};
var getPlanForInstance = function(serviceInstance, serviceClass) {
var planName = _.get(serviceInstance, 'spec.planName');
return _.find(serviceClass.plans, { name: planName });
};
var getBindParameters = function(serviceInstance, serviceClass) {
var plan = getPlanForInstance(serviceInstance, serviceClass);
if (_.has(plan, ['alphaBindingCreateParameterSchema', 'properties', 'template.openshift.io/requester-username'])) {
return AuthService.withUser().then(function(user) {
return {
'template.openshift.io/requester-username': user.metadata.name
};
});
}
return $q.when({});
};
var generateName = $filter('generateName');
var relatedObjName = generateName(_.trunc(serviceToBind, DNS1123_SUBDOMAIN_VALIDATION.maxlength - 6) + '-');
var makeBinding = function (serviceInstance, application, parameters) {
var instanceName = serviceInstance.metadata.name;
var relatedObjName = generateName(_.trunc(instanceName, DNS1123_SUBDOMAIN_VALIDATION.maxlength - 6) + '-');
var binding = {
kind: 'Binding',
apiVersion: 'servicecatalog.k8s.io/v1alpha1',
metadata: {
generateName: serviceToBind + '-'
generateName: instanceName + '-'
},
spec: {
instanceRef: {
name: serviceToBind
name: instanceName
},
secretName: relatedObjName
}
};
var appSelector = _.get(appToBind, 'spec.selector');
if (!_.isEmpty(parameters)) {
binding.spec.parameters = parameters;
}
var appSelector = _.get(application, 'spec.selector');
if (appSelector) {
if (!appSelector.matchLabels && !appSelector.matchExpressions) {
// Then this is the old format of selector, pod preset requires the new format
......@@ -1033,30 +1067,45 @@ angular.module("openshiftCommonServices")
selector: appSelector
};
}
return binding;
};
return {
bindingResource: bindingResource,
bindService: function(context, serviceToBind, appToBind) {
var newBinding = makeBinding(serviceToBind, appToBind);
getServiceClassForInstance: getServiceClassForInstance,
// Create a binding for `serviceInstance`. If an `application` API object
// is specified, also create a pod preset for that application using its
// `spec.selector`. `serviceClass` is required to determine if any
// parameters need to be set when creating the binding.
bindService: function(serviceInstance, application, serviceClass) {
return getBindParameters(serviceInstance, serviceClass).then(function (parameters) {
var newBinding = makeBinding(serviceInstance, application, parameters);
var context = {
namespace: serviceInstance.metadata.namespace
};
return DataService.create(bindingResource, null, newBinding, context);
});
},
isServiceBindable: function(serviceInstance, serviceClasses) {
if (serviceClasses && serviceInstance) {
var serviceClass = serviceClasses[serviceInstance.spec.serviceClassName];
if (serviceClass) {
var plan = _.find(serviceClass.plans, {name: serviceInstance.spec.planName});
if (plan.bindable === false) {
return false;
} else if (plan.bindable === true) {
return true;
} else {
return serviceClass.bindable;
var serviceClass = getServiceClassForInstance(serviceInstance, serviceClasses);
if (!serviceClass) {
return !!serviceInstance;
}
var plan = getPlanForInstance(serviceInstance, serviceClass);
var planBindable = _.get(plan, 'bindable');
if (planBindable === true) {
return true;
}
if (planBindable === false) {
return false;
}
return !!serviceInstance;
// If `plan.bindable` is not set, fall back to `serviceClass.bindable`.
return serviceClass.bindable;
}
};
});
......
......@@ -47,7 +47,7 @@ hawtioPluginLoader.addModule('openshiftCommonUI');
" <fieldset>\n" +
" <div class=\"radio\">\n" +
" <label ng-if=\"ctrl.allowNoBinding\">\n" +
" <input type=\"radio\" ng-model=\"ctrl.serviceToBind\" value=\"\">\n" +
" <input type=\"radio\" ng-model=\"ctrl.serviceToBind\" ng-value=\"null\">\n" +
" Do not bind at this time.\n" +
" </label>\n" +
" <div ng-if=\"ctrl.allowNoBinding\" class=\"bind-description\">\n" +
......@@ -57,7 +57,7 @@ hawtioPluginLoader.addModule('openshiftCommonUI');
" </div>\n" +
" <div ng-repeat=\"serviceInstance in ctrl.bindableServiceInstances\">\n" +
" <label>\n" +
" <input type=\"radio\" ng-model=\"ctrl.serviceToBind\" value=\"{{serviceInstance.metadata.name}}\">\n" +
" <input type=\"radio\" ng-model=\"ctrl.serviceToBind\" ng-value=\"serviceInstance\">\n" +
" {{ctrl.serviceClasses[serviceInstance.spec.serviceClassName].osbMetadata.displayName || serviceInstance.spec.serviceClassName}}\n" +
" </label>\n" +
" <div class=\"bind-description\">\n" +
......
......@@ -218,7 +218,7 @@ hawtioPluginLoader.addModule('openshiftCommonUI');
" <fieldset>\n" +
" <div class=\"radio\">\n" +
" <label ng-if=\"ctrl.allowNoBinding\">\n" +
" <input type=\"radio\" ng-model=\"ctrl.serviceToBind\" value=\"\">\n" +
" <input type=\"radio\" ng-model=\"ctrl.serviceToBind\" ng-value=\"null\">\n" +
" Do not bind at this time.\n" +
" </label>\n" +
" <div ng-if=\"ctrl.allowNoBinding\" class=\"bind-description\">\n" +
......@@ -228,7 +228,7 @@ hawtioPluginLoader.addModule('openshiftCommonUI');
" </div>\n" +
" <div ng-repeat=\"serviceInstance in ctrl.bindableServiceInstances\">\n" +
" <label>\n" +
" <input type=\"radio\" ng-model=\"ctrl.serviceToBind\" value=\"{{serviceInstance.metadata.name}}\">\n" +
" <input type=\"radio\" ng-model=\"ctrl.serviceToBind\" ng-value=\"serviceInstance\">\n" +
" {{ctrl.serviceClasses[serviceInstance.spec.serviceClassName].osbMetadata.displayName || serviceInstance.spec.serviceClassName}}\n" +
" </label>\n" +
" <div class=\"bind-description\">\n" +
......@@ -2722,29 +2722,63 @@ angular.module('openshiftCommonServices')
;'use strict';
angular.module("openshiftCommonServices")
.service("BindingService", ["$filter", "$q", "DataService", "DNS1123_SUBDOMAIN_VALIDATION", function($filter, $q, DataService, DNS1123_SUBDOMAIN_VALIDATION){
.service("BindingService",
["$filter", "$q", "AuthService", "DataService", "DNS1123_SUBDOMAIN_VALIDATION", function($filter,
$q,
AuthService,
DataService,
DNS1123_SUBDOMAIN_VALIDATION) {
var bindingResource = {
group: 'servicecatalog.k8s.io',
resource: 'bindings'
};
var makeBinding = function (serviceToBind, appToBind) {
var getServiceClassForInstance = function(serviceInstance, serviceClasses) {
var serviceClassName = _.get(serviceInstance, 'spec.serviceClassName');
return _.get(serviceClasses, [serviceClassName]);
};
var getPlanForInstance = function(serviceInstance, serviceClass) {
var planName = _.get(serviceInstance, 'spec.planName');
return _.find(serviceClass.plans, { name: planName });
};
var getBindParameters = function(serviceInstance, serviceClass) {
var plan = getPlanForInstance(serviceInstance, serviceClass);
if (_.has(plan, ['alphaBindingCreateParameterSchema', 'properties', 'template.openshift.io/requester-username'])) {
return AuthService.withUser().then(function(user) {
return {
'template.openshift.io/requester-username': user.metadata.name
};
});
}
return $q.when({});
};
var generateName = $filter('generateName');
var relatedObjName = generateName(_.trunc(serviceToBind, DNS1123_SUBDOMAIN_VALIDATION.maxlength - 6) + '-');
var makeBinding = function (serviceInstance, application, parameters) {
var instanceName = serviceInstance.metadata.name;
var relatedObjName = generateName(_.trunc(instanceName, DNS1123_SUBDOMAIN_VALIDATION.maxlength - 6) + '-');
var binding = {
kind: 'Binding',
apiVersion: 'servicecatalog.k8s.io/v1alpha1',
metadata: {
generateName: serviceToBind + '-'
generateName: instanceName + '-'
},
spec: {
instanceRef: {
name: serviceToBind
name: instanceName
},
secretName: relatedObjName
}
};
var appSelector = _.get(appToBind, 'spec.selector');
if (!_.isEmpty(parameters)) {
binding.spec.parameters = parameters;
}
var appSelector = _.get(application, 'spec.selector');
if (appSelector) {
if (!appSelector.matchLabels && !appSelector.matchExpressions) {
// Then this is the old format of selector, pod preset requires the new format
......@@ -2757,30 +2791,45 @@ angular.module("openshiftCommonServices")
selector: appSelector
};
}
return binding;
};
return {
bindingResource: bindingResource,
bindService: function(context, serviceToBind, appToBind) {
var newBinding = makeBinding(serviceToBind, appToBind);
getServiceClassForInstance: getServiceClassForInstance,
// Create a binding for `serviceInstance`. If an `application` API object
// is specified, also create a pod preset for that application using its
// `spec.selector`. `serviceClass` is required to determine if any
// parameters need to be set when creating the binding.
bindService: function(serviceInstance, application, serviceClass) {
return getBindParameters(serviceInstance, serviceClass).then(function (parameters) {
var newBinding = makeBinding(serviceInstance, application, parameters);
var context = {
namespace: serviceInstance.metadata.namespace
};
return DataService.create(bindingResource, null, newBinding, context);
});
},
isServiceBindable: function(serviceInstance, serviceClasses) {
if (serviceClasses && serviceInstance) {
var serviceClass = serviceClasses[serviceInstance.spec.serviceClassName];
if (serviceClass) {
var plan = _.find(serviceClass.plans, {name: serviceInstance.spec.planName});
if (plan.bindable === false) {
return false;
} else if (plan.bindable === true) {
return true;
} else {
return serviceClass.bindable;
var serviceClass = getServiceClassForInstance(serviceInstance, serviceClasses);
if (!serviceClass) {
return !!serviceInstance;
}
var plan = getPlanForInstance(serviceInstance, serviceClass);
var planBindable = _.get(plan, 'bindable');
if (planBindable === true) {
return true;
}
if (planBindable === false) {
return false;
}
return !!serviceInstance;
// If `plan.bindable` is not set, fall back to `serviceClass.bindable`.
return serviceClass.bindable;
}
};
}]);
......
......@@ -85,7 +85,7 @@ maxlength:253,
description:"Name must consist of lower-case letters, numbers, periods, and hyphens. It must start and end with a letter or a number."
}).constant("IS_IOS", /iPad|iPhone|iPod/.test(navigator.userAgent) && !window.MSStream), hawtioPluginLoader.addModule("openshiftCommonUI"), angular.module("openshiftCommonUI").run([ "$templateCache", function($templateCache) {
"use strict";
$templateCache.put("src/components/binding/bindApplicationForm.html", '<div class="bind-form">\n <form>\n <div class="form-group">\n <label>\n <h3>Bind a service to <strong>{{ctrl.applicationName}}</strong></h3>\n </label>\n <span class="help-block">\n Binding to a provisioned service will create a secret containing the information necessary for your application to use the service.\n </span>\n </div>\n </form>\n\n <form name="ctrl.formName">\n <fieldset>\n <div class="radio">\n <label ng-if="ctrl.allowNoBinding">\n <input type="radio" ng-model="ctrl.serviceToBind" value="">\n Do not bind at this time.\n </label>\n <div ng-if="ctrl.allowNoBinding" class="bind-description">\n <span class="help-block service-instance-name">\n You can create the binding later from your project.\n </span>\n </div>\n <div ng-repeat="serviceInstance in ctrl.bindableServiceInstances">\n <label>\n <input type="radio" ng-model="ctrl.serviceToBind" value="{{serviceInstance.metadata.name}}">\n {{ctrl.serviceClasses[serviceInstance.spec.serviceClassName].osbMetadata.displayName || serviceInstance.spec.serviceClassName}}\n </label>\n <div class="bind-description">\n <span class="pficon pficon-info"\n ng-if="!(serviceInstance | isServiceInstanceReady)"\n data-content="This service is not yet ready. If you bind to it, then the binding will be pending until the service is ready."\n data-toggle="popover"\n data-trigger="hover">\n </span>\n <span class="help-block service-instance-name">\n {{serviceInstance.metadata.name}}\n </span>\n </div>\n </div>\n <h4 ng-if="!ctrl.bindableServiceInstances.length">\n <span class="pficon pficon-info" aria-hidden="true"></span>\n <span class="help-block service-instance-name">\n There are no bindable services in this project\n </span>\n </h4>\n </div>\n </fieldset>\n </form>\n</div>\n'),
$templateCache.put("src/components/binding/bindApplicationForm.html", '<div class="bind-form">\n <form>\n <div class="form-group">\n <label>\n <h3>Bind a service to <strong>{{ctrl.applicationName}}</strong></h3>\n </label>\n <span class="help-block">\n Binding to a provisioned service will create a secret containing the information necessary for your application to use the service.\n </span>\n </div>\n </form>\n\n <form name="ctrl.formName">\n <fieldset>\n <div class="radio">\n <label ng-if="ctrl.allowNoBinding">\n <input type="radio" ng-model="ctrl.serviceToBind" ng-value="null">\n Do not bind at this time.\n </label>\n <div ng-if="ctrl.allowNoBinding" class="bind-description">\n <span class="help-block service-instance-name">\n You can create the binding later from your project.\n </span>\n </div>\n <div ng-repeat="serviceInstance in ctrl.bindableServiceInstances">\n <label>\n <input type="radio" ng-model="ctrl.serviceToBind" ng-value="serviceInstance">\n {{ctrl.serviceClasses[serviceInstance.spec.serviceClassName].osbMetadata.displayName || serviceInstance.spec.serviceClassName}}\n </label>\n <div class="bind-description">\n <span class="pficon pficon-info"\n ng-if="!(serviceInstance | isServiceInstanceReady)"\n data-content="This service is not yet ready. If you bind to it, then the binding will be pending until the service is ready."\n data-toggle="popover"\n data-trigger="hover">\n </span>\n <span class="help-block service-instance-name">\n {{serviceInstance.metadata.name}}\n </span>\n </div>\n </div>\n <h4 ng-if="!ctrl.bindableServiceInstances.length">\n <span class="pficon pficon-info" aria-hidden="true"></span>\n <span class="help-block service-instance-name">\n There are no bindable services in this project\n </span>\n </h4>\n </div>\n </fieldset>\n </form>\n</div>\n'),
$templateCache.put("src/components/binding/bindResults.html", '<div ng-if="!ctrl.error">\n <div ng-if="!(ctrl.binding | isBindingReady)" class="bind-status" ng-class="{\'text-center\': !ctrl.progressInline, \'show-progress\': !ctrl.progressInline}">\n <div class="spinner" ng-class="{\'spinner-sm\': ctrl.progressInline, \'spinner-inline\': ctrl.progressInline, \'spinner-lg\': !ctrl.progressInline}" aria-hidden="true"></div>\n <h3 class="bind-message">\n <span class="sr-only">Pending</span>\n <div class="bind-pending-message" ng-class="{\'progress-inline\': ctrl.progressInline}">The binding was created but is not ready yet.</div>\n </h3>\n </div>\n <div ng-if="(ctrl.binding | isBindingReady)">\n <div class="bind-status">\n <span class="pficon pficon-ok" aria-hidden="true"></span>\n <span class="sr-only">Success</span>\n <h3 class="bind-message">\n <strong>{{ctrl.serviceToBind}}</strong>\n <span>has been bound</span>\n <span ng-if="ctrl.bindType === \'application\'"> to <strong>{{ctrl.applicationToBind}}</strong> successfully</span>\n </h3>\n </div>\n <div class="sub-title">\n The binding operation created the secret\n <a ng-if="ctrl.secretHref && \'secrets\' | canI : \'list\'"\n ng-href="{{ctrl.secretHref}}">{{ctrl.binding.spec.secretName}}</a>\n <span ng-if="!ctrl.secretHref || !(\'secrets\' | canI : \'list\')">{{ctrl.binding.spec.secretName}}</span>\n that you may need to reference in your application.\n <span ng-if="ctrl.showPodPresets">Its data will be available to your application as environment variables.</span>\n </div>\n <div class="alert alert-info bind-info">\n <span class="pficon pficon-info" aria-hidden="true"></span>\n <span class="sr-only">Info</span>\n The binding secret will only be available to new pods. You will need to redeploy your application.\n </div>\n </div>\n</div>\n<div ng-if="ctrl.error">\n <div class="bind-status">\n <span class="pficon pficon-error-circle-o text-danger" aria-hidden="true"></span>\n <span class="sr-only">Error</span>\n <h3 class="bind-message">\n <span>Binding Failed</span>\n </h3>\n </div>\n <div class="sub-title">\n <span ng-if="ctrl.error.data.message">\n {{ctrl.error.data.message | upperFirst}}\n </span>\n <span ng-if="!ctrl.error.data.message">\n An error occurred creating the binding.\n </span>\n </div>\n</div>\n'),
$templateCache.put("src/components/binding/bindServiceForm.html", '<div class="bind-form">\n <form>\n <div class="form-group">\n <label>\n <h3>Bind <strong>{{ctrl.serviceClass.osbMetadata.displayName || ctrl.serviceClassName}}</strong> to an existing application</strong></h3>\n </label>\n <span class="help-block">Binding to a provisioned service will create a secret containing the information necessary for your application to use the service.</span>\n </div>\n </form>\n\n <form name="ctrl.formName" class="mar-bottom-lg">\n <fieldset>\n <div class="radio">\n <label class="bind-choice" ng-disabled="!ctrl.applications.length">\n <input type="radio" ng-model="ctrl.bindType" value="application" ng-disabled="!ctrl.applications.length">\n Bind to an application\n </label>\n <div class="application-select">\n <ui-select ng-model="ctrl.appToBind"\n ng-disabled="ctrl.bindType !== \'application\'"\n ng-required="ctrl.bindType === \'application\'">\n <ui-select-match placeholder="{{ctrl.applications.length ? \'Select an application\' : \'There are no applications in this project\'}}">\n <span>\n {{$select.selected.metadata.name}}\n <small class="text-muted">&ndash; {{$select.selected.kind | humanizeKind : true}}</small>\n </span>\n </ui-select-match>\n <ui-select-choices\n repeat="application in (ctrl.applications) | filter : { metadata: { name: $select.search } } track by (application | uid)"\n group-by="ctrl.groupByKind">\n <span ng-bind-html="application.metadata.name | highlight : $select.search"></span>\n </ui-select-choices>\n </ui-select>\n </div>\n <label class="bind-choice">\n <input type="radio" ng-model="ctrl.bindType" value="secret-only">\n Create a secret in my project\n </label>\n <div class="help-block bind-description">\n You can reference this secret later from any application either as environment variables or configuration files mounted as volumes.\n </div>\n <label ng-if="ctrl.allowNoBinding" class="bind-choice">\n <input type="radio" ng-model="ctrl.bindType" value="none">\n Do not bind at this time\n </label>\n <div ng-if="ctrl.allowNoBinding" class="help-block bind-description">\n You can create the binding later from your project.\n </div>\n </div>\n </fieldset>\n </form>\n</div>\n'),
$templateCache.put("src/components/create-project/createProject.html", '<form name="createProjectForm" novalidate>\n <fieldset ng-disabled="disableInputs">\n <div class="form-group">\n <label for="name" class="required">Name</label>\n <span ng-class="{\'has-error\': (createProjectForm.name.$error.pattern && createProjectForm.name.$touched) || nameTaken}">\n <input class="form-control input-lg"\n name="name"\n id="name"\n placeholder="my-project"\n type="text"\n required\n take-focus\n minlength="2"\n maxlength="63"\n pattern="[a-z0-9]([-a-z0-9]*[a-z0-9])?"\n aria-describedby="nameHelp"\n ng-model="name"\n ng-model-options="{ updateOn: \'default blur\' }"\n ng-change="nameTaken = false"\n autocorrect="off"\n autocapitalize="off"\n spellcheck="false">\n </span>\n <div>\n <span class="help-block">A unique name for the project.</span>\n </div>\n <div class="has-error">\n <span id="nameHelp" class="help-block" ng-if="createProjectForm.name.$error.required && createProjectForm.name.$dirty">\n Name is required.\n </span>\n </div>\n <div class="has-error">\n <span id="nameHelp" class="help-block" ng-if="createProjectForm.name.$error.minlength && createProjectForm.name.$touched">\n Name must have at least two characters.\n </span>\n </div>\n <div class="has-error">\n <span id="nameHelp" class="help-block" ng-if="createProjectForm.name.$error.pattern && createProjectForm.name.$touched">\n Project names may only contain lower-case letters, numbers, and dashes.\n They may not start or end with a dash.\n </span>\n </div>\n <div class="has-error">\n <span class="help-block" ng-if="nameTaken">\n This name is already in use. Please choose a different name.\n </span>\n </div>\n </div>\n\n <div class="form-group">\n <label for="displayName">Display Name</label>\n <input class="form-control input-lg"\n name="displayName"\n id="displayName"\n placeholder="My Project"\n type="text"\n ng-model="displayName">\n </div>\n\n <div class="form-group">\n <label for="description">Description</label>\n <textarea class="form-control input-lg"\n name="description"\n id="description"\n placeholder="A short description."\n ng-model="description"></textarea>\n </div>\n\n <div class="button-group">\n <button type="submit"\n class="btn btn-primary btn-lg"\n ng-class="{\'dialog-btn\': isDialog}"\n ng-click="createProject()"\n ng-disabled="createProjectForm.$invalid || nameTaken || disableInputs"\n value="">\n Create\n </button>\n <button\n class="btn btn-default btn-lg"\n ng-class="{\'dialog-btn\': isDialog}"\n ng-click="cancelCreateProject()">\n Cancel\n </button>\n </div>\n </fieldset>\n</form>\n'),
......@@ -1109,24 +1109,41 @@ return data;
}
}
};
}), angular.module("openshiftCommonServices").service("BindingService", [ "$filter", "$q", "DataService", "DNS1123_SUBDOMAIN_VALIDATION", function($filter, $q, DataService, DNS1123_SUBDOMAIN_VALIDATION) {
}), angular.module("openshiftCommonServices").service("BindingService", [ "$filter", "$q", "AuthService", "DataService", "DNS1123_SUBDOMAIN_VALIDATION", function($filter, $q, AuthService, DataService, DNS1123_SUBDOMAIN_VALIDATION) {
var bindingResource = {
group:"servicecatalog.k8s.io",
resource:"bindings"
}, makeBinding = function(serviceToBind, appToBind) {
var generateName = $filter("generateName"), relatedObjName = generateName(_.trunc(serviceToBind, DNS1123_SUBDOMAIN_VALIDATION.maxlength - 6) + "-"), binding = {
}, getServiceClassForInstance = function(serviceInstance, serviceClasses) {
var serviceClassName = _.get(serviceInstance, "spec.serviceClassName");
return _.get(serviceClasses, [ serviceClassName ]);
}, getPlanForInstance = function(serviceInstance, serviceClass) {
var planName = _.get(serviceInstance, "spec.planName");
return _.find(serviceClass.plans, {
name:planName
});
}, getBindParameters = function(serviceInstance, serviceClass) {
var plan = getPlanForInstance(serviceInstance, serviceClass);
return _.has(plan, [ "alphaBindingCreateParameterSchema", "properties", "template.openshift.io/requester-username" ]) ? AuthService.withUser().then(function(user) {
return {
"template.openshift.io/requester-username":user.metadata.name
};
}) :$q.when({});
}, generateName = $filter("generateName"), makeBinding = function(serviceInstance, application, parameters) {
var instanceName = serviceInstance.metadata.name, relatedObjName = generateName(_.trunc(instanceName, DNS1123_SUBDOMAIN_VALIDATION.maxlength - 6) + "-"), binding = {
kind:"Binding",
apiVersion:"servicecatalog.k8s.io/v1alpha1",
metadata:{
generateName:serviceToBind + "-"
generateName:instanceName + "-"
},
spec:{
instanceRef:{
name:serviceToBind
name:instanceName
},
secretName:relatedObjName
}
}, appSelector = _.get(appToBind, "spec.selector");
};
_.isEmpty(parameters) || (binding.spec.parameters = parameters);
var appSelector = _.get(application, "spec.selector");
return appSelector && (appSelector.matchLabels || appSelector.matchExpressions || (appSelector = {
matchLabels:appSelector
}), binding.spec.alphaPodPresetTemplate = {
......@@ -1136,21 +1153,20 @@ selector:appSelector
};
return {
bindingResource:bindingResource,
bindService:function(context, serviceToBind, appToBind) {
var newBinding = makeBinding(serviceToBind, appToBind);
getServiceClassForInstance:getServiceClassForInstance,
bindService:function(serviceInstance, application, serviceClass) {
return getBindParameters(serviceInstance, serviceClass).then(function(parameters) {
var newBinding = makeBinding(serviceInstance, application, parameters), context = {
namespace:serviceInstance.metadata.namespace
};
return DataService.create(bindingResource, null, newBinding, context);
});
},
isServiceBindable:function(serviceInstance, serviceClasses) {
if (serviceClasses && serviceInstance) {
var serviceClass = serviceClasses[serviceInstance.spec.serviceClassName];
if (serviceClass) {
var plan = _.find(serviceClass.plans, {
name:serviceInstance.spec.planName
});
return plan.bindable === !1 ? !1 :plan.bindable === !0 ? !0 :serviceClass.bindable;
}
}
return !!serviceInstance;
var serviceClass = getServiceClassForInstance(serviceInstance, serviceClasses);
if (!serviceClass) return !!serviceInstance;
var plan = getPlanForInstance(serviceInstance, serviceClass), planBindable = _.get(plan, "bindable");
return planBindable === !0 ? !0 :planBindable === !1 ? !1 :serviceClass.bindable;
}
};
} ]), angular.module("openshiftCommonServices").factory("Constants", function() {
......
......@@ -18,7 +18,7 @@ angular.module('openshiftCommonUI').run(['$templateCache', function($templateCac
" <fieldset>\n" +
" <div class=\"radio\">\n" +
" <label ng-if=\"ctrl.allowNoBinding\">\n" +
" <input type=\"radio\" ng-model=\"ctrl.serviceToBind\" value=\"\">\n" +
" <input type=\"radio\" ng-model=\"ctrl.serviceToBind\" ng-value=\"null\">\n" +
" Do not bind at this time.\n" +
" </label>\n" +
" <div ng-if=\"ctrl.allowNoBinding\" class=\"bind-description\">\n" +
......@@ -28,7 +28,7 @@ angular.module('openshiftCommonUI').run(['$templateCache', function($templateCac
" </div>\n" +
" <div ng-repeat=\"serviceInstance in ctrl.bindableServiceInstances\">\n" +
" <label>\n" +
" <input type=\"radio\" ng-model=\"ctrl.serviceToBind\" value=\"{{serviceInstance.metadata.name}}\">\n" +
" <input type=\"radio\" ng-model=\"ctrl.serviceToBind\" ng-value=\"serviceInstance\">\n" +
" {{ctrl.serviceClasses[serviceInstance.spec.serviceClassName].osbMetadata.displayName || serviceInstance.spec.serviceClassName}}\n" +
" </label>\n" +
" <div class=\"bind-description\">\n" +
......
......@@ -14,7 +14,7 @@
<fieldset>
<div class="radio">
<label ng-if="ctrl.allowNoBinding">
<input type="radio" ng-model="ctrl.serviceToBind" value="">
<input type="radio" ng-model="ctrl.serviceToBind" ng-value="null">
Do not bind at this time.
</label>
<div ng-if="ctrl.allowNoBinding" class="bind-description">
......@@ -24,7 +24,7 @@
</div>
<div ng-repeat="serviceInstance in ctrl.bindableServiceInstances">
<label>
<input type="radio" ng-model="ctrl.serviceToBind" value="{{serviceInstance.metadata.name}}">
<input type="radio" ng-model="ctrl.serviceToBind" ng-value="serviceInstance">
{{ctrl.serviceClasses[serviceInstance.spec.serviceClassName].osbMetadata.displayName || serviceInstance.spec.serviceClassName}}
</label>
<div class="bind-description">
......
'use strict';
angular.module("openshiftCommonServices")
.service("BindingService", function($filter, $q, DataService, DNS1123_SUBDOMAIN_VALIDATION){
.service("BindingService",
function($filter,
$q,
AuthService,
DataService,
DNS1123_SUBDOMAIN_VALIDATION) {
var bindingResource = {
group: 'servicecatalog.k8s.io',
resource: 'bindings'
};
var makeBinding = function (serviceToBind, appToBind) {
var getServiceClassForInstance = function(serviceInstance, serviceClasses) {
var serviceClassName = _.get(serviceInstance, 'spec.serviceClassName');
return _.get(serviceClasses, [serviceClassName]);
};
var getPlanForInstance = function(serviceInstance, serviceClass) {
var planName = _.get(serviceInstance, 'spec.planName');
return _.find(serviceClass.plans, { name: planName });
};
var getBindParameters = function(serviceInstance, serviceClass) {
var plan = getPlanForInstance(serviceInstance, serviceClass);
if (_.has(plan, ['alphaBindingCreateParameterSchema', 'properties', 'template.openshift.io/requester-username'])) {
return AuthService.withUser().then(function(user) {
return {
'template.openshift.io/requester-username': user.metadata.name
};
});
}
return $q.when({});
};
var generateName = $filter('generateName');
var relatedObjName = generateName(_.trunc(serviceToBind, DNS1123_SUBDOMAIN_VALIDATION.maxlength - 6) + '-');
var makeBinding = function (serviceInstance, application, parameters) {
var instanceName = serviceInstance.metadata.name;
var relatedObjName = generateName(_.trunc(instanceName, DNS1123_SUBDOMAIN_VALIDATION.maxlength - 6) + '-');
var binding = {
kind: 'Binding',
apiVersion: 'servicecatalog.k8s.io/v1alpha1',
metadata: {
generateName: serviceToBind + '-'
generateName: instanceName + '-'
},
spec: {
instanceRef: {
name: serviceToBind
name: instanceName
},
secretName: relatedObjName
}
};
var appSelector = _.get(appToBind, 'spec.selector');
if (!_.isEmpty(parameters)) {
binding.spec.parameters = parameters;
}
var appSelector = _.get(application, 'spec.selector');
if (appSelector) {
if (!appSelector.matchLabels && !appSelector.matchExpressions) {
// Then this is the old format of selector, pod preset requires the new format
......@@ -36,30 +70,45 @@ angular.module("openshiftCommonServices")
selector: appSelector
};
}
return binding;
};
return {
bindingResource: bindingResource,
bindService: function(context, serviceToBind, appToBind) {
var newBinding = makeBinding(serviceToBind, appToBind);
getServiceClassForInstance: getServiceClassForInstance,
// Create a binding for `serviceInstance`. If an `application` API object
// is specified, also create a pod preset for that application using its
// `spec.selector`. `serviceClass` is required to determine if any
// parameters need to be set when creating the binding.
bindService: function(serviceInstance, application, serviceClass) {
return getBindParameters(serviceInstance, serviceClass).then(function (parameters) {
var newBinding = makeBinding(serviceInstance, application, parameters);
var context = {
namespace: serviceInstance.metadata.namespace
};
return DataService.create(bindingResource, null, newBinding, context);
});
},
isServiceBindable: function(serviceInstance, serviceClasses) {
if (serviceClasses && serviceInstance) {
var serviceClass = serviceClasses[serviceInstance.spec.serviceClassName];
if (serviceClass) {
var plan = _.find(serviceClass.plans, {name: serviceInstance.spec.planName});
if (plan.bindable === false) {
return false;
} else if (plan.bindable === true) {
return true;
} else {
return serviceClass.bindable;
var serviceClass = getServiceClassForInstance(serviceInstance, serviceClasses);
if (!serviceClass) {
return !!serviceInstance;
}
var plan = getPlanForInstance(serviceInstance, serviceClass);
var planBindable = _.get(plan, 'bindable');
if (planBindable === true) {
return true;
}
if (planBindable === false) {
return false;
}
return !!serviceInstance;
// If `plan.bindable` is not set, fall back to `serviceClass.bindable`.
return serviceClass.bindable;
}
};
});
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment