Add ciphers options for listeners and pools
Added an option to specify the TLS ciphers used by listeners and pools. It is specifed through a string in OpenSSL syntax. Change-Id: Icead9106b06ae7610301a121e51dc5fe1a0e4056 Co-authored-by: Steven Glasford <stevenglasford@gmail.com> Story: 2006627 Task: 37193
This commit is contained in:
parent
1a29983ebc
commit
daae6d1fcd
octavia_dashboard
api/rest
static/dashboard/project/lbaasv2
releasenotes/notes
@ -185,7 +185,9 @@ def create_listener(request, **kwargs):
|
||||
timeout_member_connect=data['listener'].get('timeout_member_connect'),
|
||||
timeout_member_data=data['listener'].get('timeout_member_data'),
|
||||
timeout_tcp_inspect=data['listener'].get('timeout_tcp_inspect'),
|
||||
allowed_cidrs=data['listener'].get('allowed_cidrs')
|
||||
allowed_cidrs=data['listener'].get('allowed_cidrs'),
|
||||
# Replace empty string by None (uses default tls cipher string)
|
||||
tls_ciphers=data['listener'].get('tls_ciphers') or None,
|
||||
)
|
||||
|
||||
if data.get('pool'):
|
||||
@ -252,7 +254,9 @@ def create_pool(request, **kwargs):
|
||||
loadbalancer_id=kwargs['loadbalancer_id'],
|
||||
name=data['pool'].get('name'),
|
||||
description=data['pool'].get('description'),
|
||||
admin_state_up=data['pool'].get('admin_state_up')
|
||||
admin_state_up=data['pool'].get('admin_state_up'),
|
||||
# Replace empty string by None (uses default tls cipher string)
|
||||
tls_ciphers=data['pool'].get('tls_ciphers') or None,
|
||||
)
|
||||
|
||||
if data.get('members'):
|
||||
@ -458,7 +462,9 @@ def update_listener(request, **kwargs):
|
||||
timeout_member_connect=data['listener'].get('timeout_member_connect'),
|
||||
timeout_member_data=data['listener'].get('timeout_member_data'),
|
||||
timeout_tcp_inspect=data['listener'].get('timeout_tcp_inspect'),
|
||||
allowed_cidrs=data['listener'].get('allowed_cidrs')
|
||||
allowed_cidrs=data['listener'].get('allowed_cidrs'),
|
||||
# Replace empty string by None (uses default tls cipher string)
|
||||
tls_ciphers=data['listener'].get('tls_ciphers') or None,
|
||||
)
|
||||
|
||||
if data.get('pool'):
|
||||
@ -527,7 +533,9 @@ def update_pool(request, **kwargs):
|
||||
session_persistence=data['pool'].get('session_persistence'),
|
||||
name=data['pool'].get('name'),
|
||||
description=data['pool'].get('description'),
|
||||
admin_state_up=data['pool'].get('admin_state_up')
|
||||
admin_state_up=data['pool'].get('admin_state_up'),
|
||||
# Replace empty string by None (uses default tls cipher string)
|
||||
tls_ciphers=data['pool'].get('tls_ciphers') or None,
|
||||
)
|
||||
|
||||
# Assemble the lists of member id's to add and remove, if any exist
|
||||
|
@ -53,7 +53,8 @@
|
||||
'id', 'name', 'description', 'project_id', 'created_at', 'updated_at',
|
||||
'connection_limit', 'insert_headers', 'default_pool_id',
|
||||
'timeout_client_data', 'timeout_member_connect',
|
||||
'timeout_member_data', 'timeout_tcp_inspect', 'allowed_cidrs'
|
||||
'timeout_member_data', 'timeout_tcp_inspect', 'allowed_cidrs',
|
||||
'tls_ciphers'
|
||||
]]">
|
||||
</hz-resource-property-list>
|
||||
</div>
|
||||
|
@ -185,7 +185,8 @@
|
||||
timeout_member_connect: gettext('Member Connect Timeout'),
|
||||
timeout_member_data: gettext('Member Data Timeout'),
|
||||
timeout_tcp_inspect: gettext('TCP Inspect Timeout'),
|
||||
load_balancers: gettext('Load Balancers')
|
||||
load_balancers: gettext('Load Balancers'),
|
||||
tls_ciphers: gettext('TLS Cipher String')
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -52,7 +52,7 @@
|
||||
item="ctrl.pool"
|
||||
property-groups="[[
|
||||
'id', 'name', 'description', 'project_id', 'created_at', 'updated_at',
|
||||
'session_persistence', 'health_monitor_id']]">
|
||||
'session_persistence', 'health_monitor_id', 'tls_ciphers']]">
|
||||
</hz-resource-property-list>
|
||||
</div>
|
||||
</uib-tab>
|
||||
|
@ -175,7 +175,8 @@
|
||||
},
|
||||
loadbalancers: gettext('Load Balancers'),
|
||||
listeners: gettext('Listeners'),
|
||||
members: gettext('Members')
|
||||
members: gettext('Members'),
|
||||
tls_ciphers: gettext('TLS Cipher String')
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -48,6 +48,7 @@
|
||||
'The connection limit must be a number greater than or equal to -1.'
|
||||
);
|
||||
ctrl.timeoutError = gettext('The timeout must be a number between 0 and 31536000000.');
|
||||
ctrl.tls_ciphersError = gettext('The cipher string must conform to OpenSSL syntax.');
|
||||
|
||||
////////////
|
||||
|
||||
|
@ -69,3 +69,13 @@
|
||||
An empty list means allow from any.
|
||||
</translate>
|
||||
</p>
|
||||
<p>
|
||||
<strong translate>TLS Cipher String:</strong>
|
||||
<translate>
|
||||
A string of the allowed ciphers using the OpenSSL syntax. The syntax
|
||||
is a colon separated list of the chiphers, ex.
|
||||
"TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_GCM_SHA256"
|
||||
Note, don't include quotation marks. An empty string sets the default TLS
|
||||
Cipher String configured in Octavia.
|
||||
</translate>
|
||||
</p>
|
||||
|
@ -167,6 +167,23 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row" ng-if="model.spec.listener.protocol === 'TERMINATED_HTTPS'">
|
||||
|
||||
<div class="col-xs-12 col-sm-8 col-md-6">
|
||||
<div class="form-group"
|
||||
ng-class="{ 'has-error': listenerDetailsForm.tls_ciphers.$invalid && listenerDetailsForm.tls_ciphers.$dirty }">
|
||||
<label translate class="control-label" for="tls_ciphers">TLS Cipher String</label>
|
||||
<textarea name="tls_ciphers" id="tls_ciphers" class="form-control"
|
||||
ng-model="model.spec.listener.tls_ciphers" ng-pattern="/^([A-Z0-9_-]+:)*[A-Z0-9_-]+$/">
|
||||
</textarea>
|
||||
<span class="help-block" ng-show="listenerDetailsForm.tls_ciphers.$invalid && listenerDetailsForm.tls_ciphers.$dirty">
|
||||
{$ ::ctrl.tls_ciphersError $}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<h4 translate ng-if="model.spec.listener.protocol === 'HTTP' || model.spec.listener.protocol === 'TERMINATED_HTTPS'">Insert Headers</h4>
|
||||
|
||||
<div class="row form-group" ng-if="model.spec.listener.protocol === 'HTTP' || model.spec.listener.protocol === 'TERMINATED_HTTPS'">
|
||||
|
@ -170,7 +170,8 @@
|
||||
timeout_member_connect: 5000,
|
||||
timeout_member_data: 50000,
|
||||
timeout_tcp_inspect: 0,
|
||||
allowed_cidrs: null
|
||||
allowed_cidrs: null,
|
||||
tls_ciphers: null
|
||||
},
|
||||
l7policy: {
|
||||
id: null,
|
||||
@ -201,7 +202,8 @@
|
||||
type: null,
|
||||
cookie_name: null
|
||||
},
|
||||
admin_state_up: true
|
||||
admin_state_up: true,
|
||||
tls_ciphers: null
|
||||
},
|
||||
monitor: {
|
||||
id: null,
|
||||
@ -516,6 +518,7 @@
|
||||
if (finalSpec.listener.protocol !== 'TERMINATED_HTTPS') {
|
||||
// Remove certificate containers if not using TERMINATED_HTTPS
|
||||
delete finalSpec.certificates;
|
||||
delete finalSpec.listener.tls_ciphers;
|
||||
} else {
|
||||
var containers = [];
|
||||
angular.forEach(finalSpec.certificates, function(cert) {
|
||||
@ -803,6 +806,7 @@
|
||||
spec.timeout_member_data = listener.timeout_member_data;
|
||||
spec.timeout_tcp_inspect = listener.timeout_tcp_inspect;
|
||||
spec.allowed_cidrs = listener.allowed_cidrs;
|
||||
spec.tls_ciphers = listener.tls_ciphers;
|
||||
}
|
||||
|
||||
function setL7PolicySpec(l7policy) {
|
||||
@ -837,6 +841,7 @@
|
||||
spec.lb_algorithm = pool.lb_algorithm;
|
||||
spec.admin_state_up = pool.admin_state_up;
|
||||
spec.session_persistence = pool.session_persistence;
|
||||
spec.tls_ciphers = pool.tls_ciphers;
|
||||
}
|
||||
|
||||
function setMembersSpec(membersList) {
|
||||
|
@ -1298,10 +1298,10 @@
|
||||
it('has the right number of properties', function() {
|
||||
expect(Object.keys(model.spec).length).toBe(11);
|
||||
expect(Object.keys(model.spec.loadbalancer).length).toBe(7);
|
||||
expect(Object.keys(model.spec.listener).length).toBe(15);
|
||||
expect(Object.keys(model.spec.listener).length).toBe(16);
|
||||
expect(Object.keys(model.spec.l7policy).length).toBe(8);
|
||||
expect(Object.keys(model.spec.l7rule).length).toBe(7);
|
||||
expect(Object.keys(model.spec.pool).length).toBe(7);
|
||||
expect(Object.keys(model.spec.pool).length).toBe(8);
|
||||
expect(Object.keys(model.spec.monitor).length).toBe(11);
|
||||
expect(model.spec.members).toEqual([]);
|
||||
});
|
||||
|
@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright 2020 Red Hat, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the 'License');
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an 'AS IS' BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
(function () {
|
||||
'use strict';
|
||||
|
||||
angular
|
||||
.module('horizon.dashboard.project.lbaasv2')
|
||||
.controller('PoolDetailsController', PoolDetailsController);
|
||||
|
||||
PoolDetailsController.$inject = [
|
||||
'$scope',
|
||||
'horizon.framework.util.i18n.gettext'
|
||||
];
|
||||
|
||||
/**
|
||||
* @ngdoc controller
|
||||
* @name PoolDetailsController
|
||||
* @description
|
||||
* The `PoolDetailsController` controller provides functions for
|
||||
* configuring the pool details step of the LBaaS wizard.
|
||||
* @param $scope The angular scope object.
|
||||
* @param gettext The horizon gettext function for translation.
|
||||
* @returns undefined
|
||||
*/
|
||||
|
||||
function PoolDetailsController($scope, gettext) {
|
||||
var ctrl = this;
|
||||
|
||||
// Error text for invalid fields
|
||||
ctrl.tls_ciphersError = gettext('The cipher string must conform to OpenSSL syntax.');
|
||||
}
|
||||
})();
|
@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright 2020 Red Hat, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the 'License');
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an 'AS IS' BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
(function() {
|
||||
'use strict';
|
||||
|
||||
describe('Pool Details Step', function() {
|
||||
|
||||
beforeEach(module('horizon.framework.util.i18n'));
|
||||
beforeEach(module('horizon.dashboard.project.lbaasv2'));
|
||||
|
||||
describe('PoolDetailsController', function() {
|
||||
var ctrl, scope;
|
||||
|
||||
beforeEach(inject(function($controller, $rootScope) {
|
||||
scope = $rootScope.$new();
|
||||
ctrl = $controller('PoolDetailsController', {
|
||||
$scope: scope
|
||||
});
|
||||
}));
|
||||
|
||||
it('should define error messages for invalid fields', function() {
|
||||
expect(ctrl.tls_ciphersError).toBeDefined();
|
||||
});
|
||||
|
||||
});
|
||||
});
|
||||
})();
|
@ -42,3 +42,13 @@
|
||||
</li>
|
||||
</ul>
|
||||
</p>
|
||||
<p>
|
||||
<strong translate>TLS Cipher String:</strong>
|
||||
<translate>
|
||||
A string of the allowed ciphers using the OpenSSL syntax. The syntax
|
||||
is a colon separated list of the chiphers, ex.
|
||||
"TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_GCM_SHA256"
|
||||
Note, don't include quotation marks. An empty string sets the default TLS
|
||||
Cipher String configured in Octavia.
|
||||
</translate>
|
||||
</p>
|
@ -1,4 +1,4 @@
|
||||
<div>
|
||||
<div ng-controller="PoolDetailsController as ctrl">
|
||||
<p translate>Provide the details for the pool.</p>
|
||||
|
||||
<div class="row">
|
||||
@ -84,6 +84,23 @@
|
||||
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
|
||||
<div class="col-xs-12 col-sm-8 col-md-6">
|
||||
<div class="form-group"
|
||||
ng-class="{ 'has-error': poolDetailsForm.tls_ciphers.$invalid && poolDetailsForm.tls_ciphers.$dirty }">
|
||||
<label translate class="control-label" for="tls_ciphers">TLS Cipher String</label>
|
||||
<textarea name="tls_ciphers" id="tls_ciphers" class="form-control"
|
||||
ng-model="model.spec.pool.tls_ciphers" ng-pattern="/^([A-Z0-9_-]+:)*[A-Z0-9_-]+$/">
|
||||
</textarea>
|
||||
<span class="help-block" ng-show="poolDetailsForm.tls_ciphers.$invalid && poolDetailsForm.tls_ciphers.$dirty">
|
||||
{$ ::ctrl.tls_ciphersError $}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
|
||||
<div class="col-xs-12 col-sm-8 col-md-6">
|
||||
|
@ -0,0 +1,5 @@
|
||||
---
|
||||
features:
|
||||
- |
|
||||
Added option to specify TLS ciphers for listeners and pools.
|
||||
The ciphers are represented in OpenSSL syntax.
|
Loading…
Reference in New Issue
Block a user