Add TLS versions support for listeners and pools

Story 2006733
Task 37206

Change-Id: I0eea32565ade95d14ecf00faafc17f3dc0c15ac9
This commit is contained in:
Gregory Thiemonge 2020-11-20 12:57:47 +01:00
parent f88e327401
commit 585a6b1f12
10 changed files with 159 additions and 4 deletions

View File

@ -187,6 +187,7 @@ def create_listener(request, **kwargs):
timeout_tcp_inspect=data['listener'].get('timeout_tcp_inspect'),
# Replace empty string by None (uses default tls cipher string)
tls_ciphers=data['listener'].get('tls_ciphers') or None,
tls_versions=data['listener'].get('tls_versions') or None,
)
if data.get('pool'):
@ -257,6 +258,7 @@ def create_pool(request, **kwargs):
tls_enabled=data['pool'].get('tls_enabled'),
# Replace empty string by None (uses default tls cipher string)
tls_ciphers=data['pool'].get('tls_ciphers') or None,
tls_versions=data['pool'].get('tls_versions') or None,
)
if data.get('members'):
@ -464,6 +466,7 @@ def update_listener(request, **kwargs):
timeout_tcp_inspect=data['listener'].get('timeout_tcp_inspect'),
# Replace empty string by None (uses default tls cipher string)
tls_ciphers=data['listener'].get('tls_ciphers') or None,
tls_versions=data['listener'].get('tls_versions') or None,
)
if data.get('pool'):
@ -536,6 +539,7 @@ def update_pool(request, **kwargs):
tls_enabled=data['pool'].get('tls_enabled'),
# Replace empty string by None (uses default tls cipher string)
tls_ciphers=data['pool'].get('tls_ciphers') or None,
tls_versions=data['pool'].get('tls_versions') or None,
)
# Assemble the lists of member id's to add and remove, if any exist

View File

@ -53,7 +53,7 @@
'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', 'tls_ciphers'
'timeout_member_data', 'timeout_tcp_inspect', 'tls_versions', 'tls_ciphers'
]]">
</hz-resource-property-list>
</div>

View File

@ -182,6 +182,7 @@
timeout_member_data: gettext('Member Data Timeout'),
timeout_tcp_inspect: gettext('TCP Inspect Timeout'),
load_balancers: gettext('Load Balancers'),
tls_versions: gettext('TLS Versions'),
tls_ciphers: gettext('TLS Cipher String')
};
}

View File

@ -52,7 +52,8 @@
item="ctrl.pool"
property-groups="[[
'id', 'name', 'description', 'project_id', 'created_at', 'updated_at',
'session_persistence', 'health_monitor_id', 'tls_enabled', 'tls_ciphers']]">
'session_persistence', 'health_monitor_id', 'tls_enabled', 'tls_versions',
'tls_ciphers']]">
</hz-resource-property-list>
</div>
</uib-tab>

View File

@ -180,6 +180,7 @@
label: gettext('TLS Enabled'),
filters: ['yesno']
},
tls_versions: gettext('TLS Versions'),
tls_ciphers: gettext('TLS Cipher String')
};
}

View File

@ -178,6 +178,15 @@
<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">
<label translate class="control-label" for="name">TLS Versions</label>
<textarea name="tls_versions" id="tls_versions" class="form-control"
ng-model="model.spec.listener.tls_versions">
</textarea>
</div>
</div>
<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 }">

View File

@ -173,6 +173,7 @@
timeout_member_connect: 5000,
timeout_member_data: 50000,
timeout_tcp_inspect: 0,
tls_versions: null,
tls_ciphers: null
},
l7policy: {
@ -206,6 +207,7 @@
},
admin_state_up: true,
tls_enabled: false,
tls_versions: null,
tls_ciphers: null
},
monitor: {
@ -522,12 +524,18 @@
// Remove certificate containers if not using TERMINATED_HTTPS
delete finalSpec.certificates;
delete finalSpec.listener.tls_ciphers;
delete finalSpec.listener.tls_versions;
} else {
var containers = [];
angular.forEach(finalSpec.certificates, function(cert) {
containers.push(cert.id);
});
finalSpec.certificates = containers;
if (finalSpec.listener.tls_versions &&
finalSpec.listener.tls_versions !== '') {
// Convert multiline tls_versions field into an array
finalSpec.listener.tls_versions = finalSpec.listener.tls_versions.split('\n');
}
}
}
}
@ -544,6 +552,13 @@
finalSpec.pool.protocol = protocol === 'TERMINATED_HTTPS' ? 'HTTP' : protocol;
if (!finalSpec.pool.tls_enabled) {
delete finalSpec.pool.tls_ciphers;
delete finalSpec.pool.tls_versions;
} else {
if (finalSpec.pool.tls_versions &&
finalSpec.pool.tls_versions !== '') {
// Convert multiline tls_versions field into an array
finalSpec.pool.tls_versions = finalSpec.pool.tls_versions.split('\n');
}
}
if (angular.isObject(finalSpec.pool.session_persistence)) {
if (!finalSpec.pool.session_persistence.type) {
@ -812,6 +827,10 @@
spec.timeout_member_data = listener.timeout_member_data;
spec.timeout_tcp_inspect = listener.timeout_tcp_inspect;
spec.tls_ciphers = listener.tls_ciphers;
spec.tls_versions = listener.tls_versions;
if (spec.tls_versions) {
spec.tls_versions = spec.tls_versions.join("\n");
}
}
function setL7PolicySpec(l7policy) {
@ -848,6 +867,10 @@
spec.session_persistence = pool.session_persistence;
spec.tls_enabled = pool.tls_enabled;
spec.tls_ciphers = pool.tls_ciphers;
spec.tls_versions = pool.tls_versions;
if (spec.tls_versions) {
spec.tls_versions = spec.tls_versions.join("\n");
}
}
function setMembersSpec(membersList) {

View File

@ -1077,6 +1077,7 @@
beforeEach(function() {
includeChildResources = true;
listenerResources.pool.tls_versions = ['v1', 'v2'];
model.initialize('pool', '1234', 'loadbalancerId');
scope.$apply();
});
@ -1123,6 +1124,7 @@
expect(model.spec.pool.lb_algorithm).toBe('ROUND_ROBIN');
expect(model.spec.pool.session_persistence.type).toBe('APP_COOKIE');
expect(model.spec.pool.session_persistence.cookie_name).toBe('cookie_name');
expect(model.spec.pool.tls_versions).toBe("v1\nv2");
});
it('should initialize all monitor properties', function() {
@ -1258,6 +1260,7 @@
beforeEach(function() {
includeChildResources = true;
listenerResources.listener.protocol = 'TERMINATED_HTTPS';
listenerResources.listener.tls_versions = ['v1', 'v2'];
model.initialize('listener', '1234');
scope.$apply();
});
@ -1266,6 +1269,7 @@
expect(model.certificates.length).toBe(3);
expect(model.spec.certificates.length).toBe(1);
expect(model.spec.certificates[0].id).toBe('container2');
expect(model.spec.listener.tls_versions).toBe('v1\nv2');
});
});
@ -1298,10 +1302,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(9);
expect(Object.keys(model.spec.pool).length).toBe(10);
expect(Object.keys(model.spec.monitor).length).toBe(11);
expect(model.spec.members).toEqual([]);
});
@ -2291,6 +2295,56 @@
expect(finalSpec.listener.protocol).toBe('HTTP');
expect(finalSpec.listener.protocol_port).toBe(80);
expect(finalSpec.pool.name).toBe('Pool 1');
expect(finalSpec.pool.description).toBe('pool description');
expect(finalSpec.pool.protocol).toBe('HTTP');
expect(finalSpec.pool.lb_algorithm).toBe('ROUND_ROBIN');
expect(finalSpec.pool.session_persistence.type).toBe('APP_COOKIE');
expect(finalSpec.pool.session_persistence.cookie_name).toBe('cookie_name');
expect(finalSpec.pool.tls_versions).toBeUndefined();
expect(finalSpec.members.length).toBe(2);
expect(finalSpec.members[0].id).toBe('1234');
expect(finalSpec.members[0].address).toBe('1.2.3.4');
expect(finalSpec.members[0].subnet_id).toBe('subnet-1');
expect(finalSpec.members[0].protocol_port).toBe(80);
expect(finalSpec.members[0].weight).toBe(1);
expect(finalSpec.members[1].id).toBe('5678');
expect(finalSpec.members[1].address).toBe('5.6.7.8');
expect(finalSpec.members[1].subnet_id).toBe('subnet-1');
expect(finalSpec.members[1].protocol_port).toBe(80);
expect(finalSpec.members[1].weight).toBe(1);
expect(finalSpec.monitor.type).toBe('HTTP');
expect(finalSpec.monitor.delay).toBe(1);
expect(finalSpec.monitor.max_retries).toBe(1);
expect(finalSpec.monitor.max_retries_down).toBe(1);
expect(finalSpec.monitor.timeout).toBe(1);
});
});
describe('Model submit function (edit listener TERMINATED_HTTPS)', function() {
beforeEach(function() {
includeChildResources = true;
listenerResources.listener.protocol = 'TERMINATED_HTTPS';
listenerResources.listener.tls_versions = ['v1', 'v2'];
model.initialize('listener', '1234');
scope.$apply();
});
it('should set final spec properties', function() {
var finalSpec = model.submit();
expect(finalSpec.loadbalancer).toBeUndefined();
expect(finalSpec.listener.name).toBe('Listener 1');
expect(finalSpec.listener.description).toBe('listener description');
expect(finalSpec.listener.protocol).toBe('TERMINATED_HTTPS');
expect(finalSpec.listener.protocol_port).toBe(80);
expect(finalSpec.listener.tls_versions).toContain('v1');
expect(finalSpec.listener.tls_versions).toContain('v2');
expect(finalSpec.pool.name).toBe('Pool 1');
expect(finalSpec.pool.description).toBe('pool description');
expect(finalSpec.pool.protocol).toBe('HTTP');
@ -2405,6 +2459,7 @@
beforeEach(function() {
includeChildResources = true;
listenerResources.pool.tls_enabled = true;
listenerResources.pool.tls_versions = ['v1', 'v2'];
listenerResources.pool.tls_ciphers = "A:B:C";
model.initialize('pool', 'poolId', 'loadbalancerId');
scope.$apply();
@ -2424,6 +2479,8 @@
expect(finalSpec.pool.session_persistence.type).toBe('APP_COOKIE');
expect(finalSpec.pool.session_persistence.cookie_name).toBe('cookie_name');
expect(finalSpec.pool.tls_enabled).toBe(true);
expect(finalSpec.pool.tls_versions).toContain('v1');
expect(finalSpec.pool.tls_versions).toContain('v2');
expect(finalSpec.pool.tls_ciphers).toBe("A:B:C");
expect(finalSpec.members.length).toBe(2);
@ -2446,6 +2503,52 @@
});
});
describe('Model submit function (edit pool tls_enabled without tls_versions)', function() {
beforeEach(function() {
includeChildResources = true;
listenerResources.pool.tls_enabled = true;
listenerResources.pool.tls_versions = '';
model.initialize('pool', 'poolId', 'loadbalancerId');
scope.$apply();
});
it('should set final spec properties', function() {
var finalSpec = model.submit();
expect(finalSpec.loadbalancer).toBeUndefined();
expect(finalSpec.listener).toBeUndefined();
expect(finalSpec.pool.name).toBe('Pool 1');
expect(finalSpec.pool.description).toBe('pool description');
expect(finalSpec.pool.protocol).toBe('HTTP');
expect(finalSpec.pool.lb_algorithm).toBe('ROUND_ROBIN');
expect(finalSpec.pool.session_persistence.type).toBe('APP_COOKIE');
expect(finalSpec.pool.session_persistence.cookie_name).toBe('cookie_name');
expect(finalSpec.pool.tls_enabled).toBe(true);
expect(finalSpec.pool.tls_versions).toBe('');
expect(finalSpec.members.length).toBe(2);
expect(finalSpec.members[0].id).toBe('1234');
expect(finalSpec.members[0].address).toBe('1.2.3.4');
expect(finalSpec.members[0].subnet_id).toBe('subnet-1');
expect(finalSpec.members[0].protocol_port).toBe(80);
expect(finalSpec.members[0].weight).toBe(1);
expect(finalSpec.members[1].id).toBe('5678');
expect(finalSpec.members[1].address).toBe('5.6.7.8');
expect(finalSpec.members[1].subnet_id).toBe('subnet-1');
expect(finalSpec.members[1].protocol_port).toBe(80);
expect(finalSpec.members[1].weight).toBe(1);
expect(finalSpec.monitor.type).toBe('HTTP');
expect(finalSpec.monitor.delay).toBe(1);
expect(finalSpec.monitor.max_retries).toBe(1);
expect(finalSpec.monitor.max_retries_down).toBe(1);
expect(finalSpec.monitor.timeout).toBe(1);
});
});
describe('Model submit function (update member list)', function() {
beforeEach(function() {

View File

@ -124,6 +124,15 @@
<div class="row" ng-if="model.spec.pool.tls_enabled">
<div class="col-xs-12 col-sm-8 col-md-6">
<div class="form-group">
<label translate class="control-label" for="name">TLS Versions</label>
<textarea name="tls_versions" id="tls_versions" class="form-control"
ng-model="model.spec.pool.tls_versions">
</textarea>
</div>
</div>
<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 }">

View File

@ -0,0 +1,4 @@
---
features:
- |
Add support for setting TLS Versions parameter in listeners and pools.