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

Let users paste certificate values #1068

Merged
merged 2 commits into from
Dec 22, 2016
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
11 changes: 5 additions & 6 deletions app/scripts/directives/oscFileInput.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,7 @@ angular.module('openshiftConsole')
model: "=",
required: "=",
disabled: "=ngDisabled",
// Show the file contents below the file input.
showValues: "=",
showTextArea: '=',
helpText: "@?",
dropZoneId: "@?"
},
Expand All @@ -24,7 +23,7 @@ angular.module('openshiftConsole')
var dropMessageSelector = "#" + scope.dropMessageID,
highlightDropZone = false,
showDropZone = false,
inputFileField = element.find('input[type=file]')[0];
inputFileField = element.find('input[type=file]');
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: we could do inputFileField = element.find('input[type=file]')[0]; or inputFileField = _.first(element.find()) here & not have to repeat the [0] a few places below.

Copy link
Member Author

Choose a reason for hiding this comment

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

Unfortunately I can't because I need the jQuery object in one place :/

Copy link
Contributor

Choose a reason for hiding this comment

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

Ah, true, because of the .change on 73, no worries!


setTimeout(addDropZoneListeners);

Expand Down Expand Up @@ -68,11 +67,11 @@ angular.module('openshiftConsole')
scope.cleanInputValues = function() {
scope.model = '';
scope.fileName = '';
inputFileField.value = "";
inputFileField[0].value = "";
};

element.change(function() {
addFile(inputFileField.files[0]);
inputFileField.change(function() {
addFile(inputFileField[0].files[0]);
});

// Add listeners for the dropZone element
Expand Down
85 changes: 62 additions & 23 deletions app/scripts/directives/oscRouting.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,22 +41,31 @@ angular.module("openshiftConsole")
hostReadOnly: "="
},
templateUrl: 'views/directives/osc-routing.html',
controller: function($scope) {
$scope.disableCertificateInputs = function() {
var termination = _.get($scope, 'route.tls.termination');
link: function(scope, element, attrs, formCtl) {
scope.form = formCtl;
scope.controls = {};
scope.options = {
secureRoute: false,
alternateServices: false
};

scope.disableWildcards = Constants.DISABLE_WILDCARD_ROUTES;
scope.disableCertificateInputs = function() {
var termination = _.get(scope, 'route.tls.termination');
return !termination || termination === 'passthrough';
};
$scope.insecureTrafficOptions = [

scope.insecureTrafficOptions = [
{value: '', label: 'None'},
{value: 'Allow', label: 'Allow'},
{value: 'Redirect', label: 'Redirect'}
];
},
link: function(scope, element, attrs, formCtl) {
scope.form = formCtl;
scope.controls = {};

scope.disableWildcards = Constants.DISABLE_WILDCARD_ROUTES;
if (!_.has(scope, 'route.tls.insecureEdgeTerminationPolicy')) {
// Initialize the value to the empty string so the option 'None' is
// shown in the select.
_.set(scope, 'route.tls.insecureEdgeTerminationPolicy', '');
}

// Use different patterns for validating hostnames if wildcard subdomains are supported.
if (scope.disableWildcards) {
Expand Down Expand Up @@ -119,6 +128,8 @@ angular.module("openshiftConsole")
return _.includes(iteratee, value, index + 1);
}).value();
formCtl.$setValidity("duplicateServices", !scope.duplicateServices.length);

scope.options.alternateServices = !_.isEmpty(alternateServices);
}, true);

var showCertificateWarning = function() {
Expand All @@ -140,52 +151,61 @@ angular.module("openshiftConsole")
// Show a warning if previously-set certificates won't be used because
// the TLS termination is now incompatible.
scope.$watch('route.tls.termination', function() {
scope.secureRoute = !!_.get(scope, 'route.tls.termination');
scope.options.secureRoute = !!_.get(scope, 'route.tls.termination');
scope.showCertificatesNotUsedWarning = showCertificateWarning();
});

var previousTermination;
scope.$watch('secureRoute', function(newValue, oldValue) {
scope.$watch('options.secureRoute', function(newValue, oldValue) {
if (newValue === oldValue) {
return;
}

// Set the default behavior of insecure connections to 'None'
if (newValue && !_.get(scope, 'route.tls.insecureEdgeTerminationPolicy')) {
_.set(scope, 'route.tls.insecureEdgeTerminationPolicy', scope.insecureTrafficOptions[0]);
}

var termination = _.get(scope, 'route.tls.termination');
if (!scope.securetRoute && termination) {
// Remember previous value if user switches back to secure.
previousTermination = termination;
delete scope.route.tls.termination;
}

if (scope.secureRoute && !termination) {
if (scope.options.secureRoute && !termination) {
// Restore previous termination value or default to edge if no previous value.
_.set(scope, 'route.tls.termination', previousTermination || 'edge');
}
});

scope.$watch('options.alternateServices', function(alternateServices, previousValue) {
if (alternateServices === previousValue) {
return;
}

if (!alternateServices) {
scope.route.alternateServices = [];
}

if (alternateServices && _.isEmpty(scope.route.alternateServices)) {
scope.addAlternateService();
}
});

scope.addAlternateService = function() {
scope.route.alternateServices = scope.route.alternateServices || [];
var firstUnselected = _.find(scope.services, function(service) {
return service !== scope.route.to.service && !_.some(scope.route.alternateServices, { service: service });
});

if (!_.has(scope, 'route.to.weight')) {
_.set(scope, 'route.to.weight', 1);
}

// Add a new value.
scope.route.alternateServices.push({
service: firstUnselected,
weight: 1
});

if (!_.has(scope, 'route.to.weight')) {
_.set(scope, 'route.to.weight', 1);
}
};

scope.weightAsPercentage = function(weight) {
scope.weightAsPercentage = function(weight, format) {
weight = weight || 0;

var total = _.get(scope, 'route.to.weight', 0);
Expand All @@ -198,10 +218,29 @@ angular.module("openshiftConsole")
}

var percentage = (weight / total) * 100;
return d3.round(percentage, 1) + '%';
return format ? (d3.round(percentage, 1) + '%') : percentage;
};

var initializingSlider = false;
scope.$watch('route.alternateServices.length', function(alternateServicesCount) {
if (alternateServicesCount === 0 && _.has(scope, 'route.to.weight')) {
// Reset the primary service weight. This rebalances the percentages when adding a new alternate service.
delete scope.route.to.weight;
}

if (alternateServicesCount === 1) {
initializingSlider = true;
scope.controls.rangeSlider = scope.weightAsPercentage(scope.route.to.weight);
}
});

scope.$watch('controls.rangeSlider', function(weight, previous) {
// Don't update the routes if we're setting the initial slider value.
if (initializingSlider) {
initializingSlider = false;
return;
}

if (weight === previous) {
return;
}
Expand Down
6 changes: 6 additions & 0 deletions app/styles/_forms.less
Original file line number Diff line number Diff line change
Expand Up @@ -61,3 +61,9 @@
}
}
}

.osc-file-input textarea {
font-family: @font-family-monospace;
// Use the same spacing as `help-block` so the textarea is evenly spaced under the help text.
margin: 5px 0;
}
6 changes: 1 addition & 5 deletions app/views/directives/create-secret.html
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,6 @@
model="newSecret.data.cacert"
drop-zone-id="cacert"
help-text="Upload your ca.crt file."
show-values="false"
required="true"></osc-file-input>
<div ui-ace="{
mode: 'txt',
Expand All @@ -134,8 +133,7 @@
id="private-key-file-input"
model="newSecret.data.privateKey"
drop-zone-id="private-key"
help-text="Upload your private SSH key file."
show-values="false"></osc-file-input>
help-text="Upload your private SSH key file."></osc-file-input>
<div ui-ace="{
theme: 'eclipse',
rendererOptions: {
Expand Down Expand Up @@ -166,7 +164,6 @@
model="newSecret.data.gitconfig"
drop-zone-id="gitconfig"
help-text="Upload your .gitconfig or file."
show-values="false"
required="true"></osc-file-input>
<div ui-ace="{
mode: 'ini',
Expand Down Expand Up @@ -271,7 +268,6 @@
model="newSecret.data.dockerConfig"
drop-zone-id="docker-config"
help-text="Upload a .dockercfg or .docker/config.json file"
show-values="false"
required="true"></osc-file-input>
<div ui-ace="{
mode: 'json',
Expand Down
3 changes: 1 addition & 2 deletions app/views/directives/edit-config-map.html
Original file line number Diff line number Diff line change
Expand Up @@ -91,8 +91,7 @@
<osc-file-input
model="item.value"
drop-zone-id="drop-zone-{{$id}}"
help-text="Enter a value for the config map entry or use the contents of a file."
show-values="false"></osc-file-input>
help-text="Enter a value for the config map entry or use the contents of a file."></osc-file-input>
<div ui-ace="{
theme: 'eclipse',
rendererOptions: {
Expand Down
3 changes: 1 addition & 2 deletions app/views/directives/from-file.html
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,7 @@
model="editorContent"
drop-zone-id="from-file"
help-text="Upload file by dragging & dropping, selecting it, or pasting from the clipboard."
ng-disabled="false"
show-values="false"></osc-file-input>
ng-disabled="false"></osc-file-input>
<div ui-ace="{
mode: 'yaml',
theme: 'eclipse',
Expand Down
70 changes: 36 additions & 34 deletions app/views/directives/osc-file-input.html
Original file line number Diff line number Diff line change
@@ -1,38 +1,40 @@
<div ng-attr-id="{{dropMessageID}}" class="drag-and-drop-zone">
<p>Drop file here</p>
</div>
<div class="input-group">
<input
type="text"
class="form-control"
ng-model="fileName"
readonly
ng-show="supportsFileUpload"
<div class="osc-file-input">
<div ng-attr-id="{{dropMessageID}}" class="drag-and-drop-zone">
<p>Drop file here</p>
</div>
<div class="input-group">
<input
type="text"
class="form-control"
ng-model="fileName"
readonly
ng-show="supportsFileUpload"
ng-disabled="disabled"
ng-attr-aria-describedby="{{helpText ? helpID : undefined}}">
<span class="input-group-btn">
<span class="btn btn-default btn-file" ng-show="supportsFileUpload" ng-attr-disabled="{{ disabled || undefined }}">
Browse&hellip;
<input type="file" ng-disabled="disabled" class="form-control">
</span>
</span>
</div>
<div ng-if="helpText">
<span ng-attr-id="{{helpID}}" class="help-block">{{::helpText}}</span>
</div>
<div class="has-error" ng-show="uploadError">
<span class="help-block">There was an error reading the file. Please copy the file content into the text area.</span>
</div>
<textarea class="form-control"
rows="5"
ng-show="showTextArea || !supportsFileUpload"
ng-model="model"
ng-required="required"
ng-disabled="disabled"
autocorrect="off"
autocapitalize="off"
spellcheck="false"
ng-attr-aria-describedby="{{helpText ? helpID : undefined}}">
<span class="input-group-btn">
<span class="btn btn-default btn-file" ng-show="supportsFileUpload" ng-attr-disabled="{{ disabled || undefined }}">
Browse&hellip;
<input type="file" ng-disabled="disabled" class="form-control">
</span>
</span>
</div>
<textarea class="form-control"
rows="8"
ng-hide="supportsFileUpload"
ng-model="model"
ng-required="required"
ng-disabled="disabled"
ng-attr-aria-describedby="{{helpText ? helpID : undefined}}">
</textarea>
<div ng-if="helpText">
<span ng-attr-id="{{helpID}}" class="help-block">{{::helpText}}</span>
</div>
<div class="has-error" ng-show="uploadError">
<span class="help-block">There was an error reading the file. Please copy the file content into the text area.</span>
</div>
</textarea>

<div ng-if="model && showValues && supportsFileUpload">
<pre ng-if="model && showValues && supportsFileUpload" class="clipped scroll">{{model}}</pre>
<a href="" ng-show="(model || fileName) && !disabled" ng-click="cleanInputValues()">Clear Value</a>
</div>
<a href="" ng-show="model || fileName" class="clear-btn" ng-click="cleanInputValues()">Clear Value</a>
Loading