From b7ea70a02ca16a96f01cbc6b2d9737ef88a74caf Mon Sep 17 00:00:00 2001 From: German Eichberger Date: Tue, 30 Jan 2018 14:47:52 -0800 Subject: [PATCH] Gate API test for the lbaasv2-proxy plugin Depends-On: https://review.openstack.org/559842 Change-Id: I87a53b45f0d9bbbe6426c588e68de3e07d22cc86 --- .../services/loadbalancer/proxy_plugin.py | 66 +++++++++++++++++-- neutron_lbaas/tests/contrib/decode_args.sh | 2 +- neutron_lbaas/tests/contrib/gate_hook.sh | 6 ++ neutron_lbaas/tests/tempest/v2/api/base.py | 2 + .../neutron-lbaasv2-dsvm-api-proxy/post.yaml | 15 +++++ .../neutron-lbaasv2-dsvm-api-proxy/run.yaml | 60 +++++++++++++++++ zuul.d/jobs.yaml | 7 ++ zuul.d/projects.yaml | 2 + 8 files changed, 152 insertions(+), 8 deletions(-) create mode 100644 playbooks/legacy/neutron-lbaasv2-dsvm-api-proxy/post.yaml create mode 100644 playbooks/legacy/neutron-lbaasv2-dsvm-api-proxy/run.yaml diff --git a/neutron_lbaas/services/loadbalancer/proxy_plugin.py b/neutron_lbaas/services/loadbalancer/proxy_plugin.py index c8b5674d0..e8b3b8198 100644 --- a/neutron_lbaas/services/loadbalancer/proxy_plugin.py +++ b/neutron_lbaas/services/loadbalancer/proxy_plugin.py @@ -16,6 +16,7 @@ import functools from neutron.db import servicetype_db as st_db from neutron.services import provider_configuration as pconf +from neutron_lib import constants as n_constants from neutron_lib import exceptions as lib_exc from oslo_config import cfg from oslo_log import log as logging @@ -30,8 +31,7 @@ VERSION = 'v2.0' OCTAVIA_PROXY_CLIENT = ( "LBaaS V2 Octavia Proxy/{version} " "(https://wiki.openstack.org/wiki/Octavia)").format(version=VERSION) -FILTER = ['vip_address', 'vip_network_id', 'flavor_id', - 'provider', 'redirect_pool_id'] +FILTER = ['vip_address', 'vip_network_id', 'redirect_pool_id'] LOADBALANCER = 'loadbalancer' LISTENER = 'listener' @@ -171,7 +171,8 @@ class LoadBalancerProxyPluginv2(loadbalancerv2.LoadBalancerPluginBaseV2): res = {} for k in map: if k not in keys: - if map[k] or map[k] == '' or isinstance(map[k], bool): + if (map[k] or map[k] == '' or isinstance(map[k], bool) + ) and map[k] != n_constants.ATTR_NOT_SPECIFIED: res[k] = map[k] if 'tenant_id' in res: res['project_id'] = res.pop('tenant_id') @@ -270,6 +271,7 @@ class LoadBalancerProxyPluginv2(loadbalancerv2.LoadBalancerPluginBaseV2): sub_resource=None, resource_id=None): # clean up the map resource_ = resource if not sub_resource else sub_resource + LOG.debug("Resource = %s", res) r = self._filter(FILTER, res[resource_]) res = self.put('{}/{}'.format(self._path( resource, sub_resource, resource_id), id), @@ -322,14 +324,31 @@ class LoadBalancerProxyPluginv2(loadbalancerv2.LoadBalancerPluginBaseV2): def get_pools(self, context, filters=None, fields=None): return self._get_resources(POOL, context, filters, fields) + def _clean_session_persistence(self, res): + session_persistence = res.get('session_persistence') + if session_persistence: + if 'persistence_granularity' in session_persistence: + del session_persistence['persistence_granularity'] + if 'persistence_timeout' in session_persistence: + del session_persistence['persistence_timeout'] + def get_pool(self, context, id, fields=None): - return self._get_resource(POOL, context, id, fields) + res = self._get_resource(POOL, context, id, fields) + # force conformance with the old API (tests fail on additional fields) + self._clean_session_persistence(res) + return res def create_pool(self, context, pool): - return self._create_resource(POOL, context, pool) + res = self._create_resource(POOL, context, pool) + # force conformance with the old API (tests fail on additional fields) + self._clean_session_persistence(res) + return res def update_pool(self, context, id, pool): - return self._update_resource(POOL, context, id, pool) + res = self._update_resource(POOL, context, id, pool) + # force conformance with the old API (tests fail on additional fields) + self._clean_session_persistence(res) + return res def delete_pool(self, context, id): return self._delete_resource(POOL, context, id) @@ -362,9 +381,43 @@ class LoadBalancerProxyPluginv2(loadbalancerv2.LoadBalancerPluginBaseV2): return self._get_resource(HEALTH_MONITOR, context, id, fields) def create_healthmonitor(self, context, healthmonitor): + if healthmonitor[HEALTH_MONITOR].get( + 'type') == constants.HEALTH_MONITOR_HTTPS: + # it defaults to GET which is not allowed with HTTPS + # so remove it for backwards compatibility with a lax + # validator + if healthmonitor[HEALTH_MONITOR].get('http_method') == 'GET': + healthmonitor[HEALTH_MONITOR].pop('http_method') + # it defaults to '/' which is not allowed with HTTPS + # so remove it for backwards compatibility with a lax + # validator + if healthmonitor[HEALTH_MONITOR].get('url_path') == '/': + healthmonitor[HEALTH_MONITOR].pop('url_path') + # it defaults to '200' which is not allowed with HTTPS + # so remove it for backwards compatibility with a lax + # validator + if healthmonitor[HEALTH_MONITOR].get('expected_codes') == '200': + healthmonitor[HEALTH_MONITOR].pop('expected_codes') return self._create_resource(HEALTH_MONITOR, context, healthmonitor) def update_healthmonitor(self, context, id, healthmonitor): + if healthmonitor[HEALTH_MONITOR].get( + 'type') == constants.HEALTH_MONITOR_HTTPS: + # it defaults to GET which is not allowed with HTTPS + # so remove it for backwards compatibility with a lax + # validator + if healthmonitor[HEALTH_MONITOR].get('http_method') == 'GET': + healthmonitor[HEALTH_MONITOR].pop('http_method') + # it defaults to '/' which is not allowed with HTTPS + # so remove it for backwards compatibility with a lax + # validator + if healthmonitor[HEALTH_MONITOR].get('url_path') == '/': + healthmonitor[HEALTH_MONITOR].pop('url_path') + # it defaults to '200' which is not allowed with HTTPS + # so remove it for backwards compatibility with a lax + # validator + if healthmonitor[HEALTH_MONITOR].get('expected_codes') == '200': + healthmonitor[HEALTH_MONITOR].pop('expected_codes') return self._update_resource(HEALTH_MONITOR, context, id, healthmonitor) @@ -378,7 +431,6 @@ class LoadBalancerProxyPluginv2(loadbalancerv2.LoadBalancerPluginBaseV2): pass def statuses(self, context, loadbalancer_id): - LOG.debug("Statuses called!") return self._get_resources(LOADBALANCER, context, sub_resource=STATUS, resource_id=loadbalancer_id, pass_through=True) diff --git a/neutron_lbaas/tests/contrib/decode_args.sh b/neutron_lbaas/tests/contrib/decode_args.sh index 65cce99d0..f6fd72458 100644 --- a/neutron_lbaas/tests/contrib/decode_args.sh +++ b/neutron_lbaas/tests/contrib/decode_args.sh @@ -47,7 +47,7 @@ case $testtype in if [ "$lbaasversion" = "lbaasv2" ]; then case "$lbaasenv" in - "api"|"healthmonitor"|"listener"|"loadbalancer"|"member"|"minimal"|"pool"|"proxy_octavia") + "api"|"healthmonitor"|"listener"|"loadbalancer"|"member"|"minimal"|"pool"|"proxy_octavia"|"lbaasv2_proxy") testenv="apiv2" ;; "scenario") diff --git a/neutron_lbaas/tests/contrib/gate_hook.sh b/neutron_lbaas/tests/contrib/gate_hook.sh index 9eebeb2d4..5a01bec23 100755 --- a/neutron_lbaas/tests/contrib/gate_hook.sh +++ b/neutron_lbaas/tests/contrib/gate_hook.sh @@ -46,6 +46,12 @@ function _setup_octavia { export OCTAVIA_USE_LEGACY_RBAC=True " fi + if [[ "$lbaasenv" == "lbaasv2_proxy" ]]; then + export DEVSTACK_LOCAL_CONFIG+=" + export OCTAVIA_USE_LEGACY_RBAC=True + export LBAASV2_PLUGIN=lbaasv2-proxy + " + fi # Use infra's cached version of the file if [ -f /opt/stack/new/devstack/files/get-pip.py ]; then export DEVSTACK_LOCAL_CONFIG+=" diff --git a/neutron_lbaas/tests/tempest/v2/api/base.py b/neutron_lbaas/tests/tempest/v2/api/base.py index 44f37187f..e9fce067a 100644 --- a/neutron_lbaas/tests/tempest/v2/api/base.py +++ b/neutron_lbaas/tests/tempest/v2/api/base.py @@ -339,6 +339,8 @@ class BaseTestCase(base.BaseNetworkTest): if wait: self._wait_for_load_balancer_status( self.load_balancer.get('id')) + health_monitor = self.health_monitors_client.get_health_monitor( + health_monitor_id) return health_monitor @classmethod diff --git a/playbooks/legacy/neutron-lbaasv2-dsvm-api-proxy/post.yaml b/playbooks/legacy/neutron-lbaasv2-dsvm-api-proxy/post.yaml new file mode 100644 index 000000000..e07f5510a --- /dev/null +++ b/playbooks/legacy/neutron-lbaasv2-dsvm-api-proxy/post.yaml @@ -0,0 +1,15 @@ +- hosts: primary + tasks: + + - name: Copy files from {{ ansible_user_dir }}/workspace/ on node + synchronize: + src: '{{ ansible_user_dir }}/workspace/' + dest: '{{ zuul.executor.log_root }}' + mode: pull + copy_links: true + verify_host: true + rsync_opts: + - --include=/logs/** + - --include=*/ + - --exclude=* + - --prune-empty-dirs diff --git a/playbooks/legacy/neutron-lbaasv2-dsvm-api-proxy/run.yaml b/playbooks/legacy/neutron-lbaasv2-dsvm-api-proxy/run.yaml new file mode 100644 index 000000000..85162ab4c --- /dev/null +++ b/playbooks/legacy/neutron-lbaasv2-dsvm-api-proxy/run.yaml @@ -0,0 +1,60 @@ +- hosts: all + name: Autoconverted job legacy-neutron-lbaasv2-dsvm-api from old job gate-neutron-lbaasv2-dsvm-api-ubuntu-xenial + tasks: + + - name: Ensure legacy workspace directory + file: + path: '{{ ansible_user_dir }}/workspace' + state: directory + + - shell: + cmd: | + set -e + set -x + cat > clonemap.yaml << EOF + clonemap: + - name: openstack-infra/devstack-gate + dest: devstack-gate + EOF + /usr/zuul-env/bin/zuul-cloner -m clonemap.yaml --cache-dir /opt/git \ + git://git.openstack.org \ + openstack-infra/devstack-gate + executable: /bin/bash + chdir: '{{ ansible_user_dir }}/workspace' + environment: '{{ zuul | zuul_legacy_vars }}' + + - shell: + cmd: | + set -e + set -x + export PYTHONUNBUFFERED=true + export DEVSTACK_GATE_TEMPEST=1 + export DEVSTACK_GATE_TEMPEST_NOTESTS=1 + export DEVSTACK_GATE_EXERCISES=0 + export DEVSTACK_GATE_NEUTRON=1 + export DEVSTACK_GATE_INSTALL_TESTONLY=1 + export BRANCH_OVERRIDE=default + if [ "$BRANCH_OVERRIDE" != "default" ] ; then + export OVERRIDE_ZUUL_BRANCH=$BRANCH_OVERRIDE + fi + export PROJECTS="openstack/barbican $PROJECTS" + export PROJECTS="openstack/python-barbicanclient $PROJECTS" + export PROJECTS="openstack/diskimage-builder $PROJECTS" + export PROJECTS="openstack/neutron-lbaas $PROJECTS" + export PROJECTS="openstack/octavia $PROJECTS" + + function gate_hook { + $BASE/new/neutron-lbaas/neutron_lbaas/tests/contrib/gate_hook.sh tempest lbaasv2 lbaasv2_proxy + } + export -f gate_hook + + function post_test_hook { + $BASE/new/neutron-lbaas/neutron_lbaas/tests/contrib/post_test_hook.sh tempest lbaasv2 lbaasv2_proxy + } + export -f post_test_hook + + cp devstack-gate/devstack-vm-gate-wrap.sh ./safe-devstack-vm-gate-wrap.sh + ./safe-devstack-vm-gate-wrap.sh + executable: /bin/bash + chdir: '{{ ansible_user_dir }}/workspace' + environment: '{{ zuul | zuul_legacy_vars }}' diff --git a/zuul.d/jobs.yaml b/zuul.d/jobs.yaml index e36e7c82b..eab44a311 100644 --- a/zuul.d/jobs.yaml +++ b/zuul.d/jobs.yaml @@ -23,6 +23,13 @@ run: playbooks/legacy/neutron-lbaasv2-dsvm-api/run.yaml post-run: playbooks/legacy/neutron-lbaasv2-dsvm-api/post.yaml +- job: + name: neutron-lbaasv2-dsvm-api-proxy + parent: nlbaas-legacy-dsvm-base + run: playbooks/legacy/neutron-lbaasv2-dsvm-api-proxy/run.yaml + post-run: playbooks/legacy/neutron-lbaasv2-dsvm-api-proxy/post.yaml + + - job: name: neutron-lbaasv2-dsvm-py3x-api parent: nlbaas-legacy-dsvm-base diff --git a/zuul.d/projects.yaml b/zuul.d/projects.yaml index 36effccc6..067745d59 100644 --- a/zuul.d/projects.yaml +++ b/zuul.d/projects.yaml @@ -3,6 +3,7 @@ jobs: - lbaas-tox-lower-constraints - neutron-lbaasv2-dsvm-api + - neutron-lbaasv2-dsvm-api-proxy - neutron-lbaasv2-dsvm-py3x-api: branches: ^(?!stable/ocata).*$ - neutron-lbaasv2-dsvm-api-namespace @@ -21,6 +22,7 @@ jobs: - lbaas-tox-lower-constraints - neutron-lbaasv2-dsvm-api + - neutron-lbaasv2-dsvm-api-proxy - neutron-lbaasv2-dsvm-py3x-api: branches: ^(?!stable/ocata).*$ - neutron-lbaasv2-dsvm-api-namespace