neutron-fwaas-8.0.0/ 0000775 0005670 0005671 00000000000 12701410073 015444 5 ustar jenkins jenkins 0000000 0000000 neutron-fwaas-8.0.0/etc/ 0000775 0005670 0005671 00000000000 12701410073 016217 5 ustar jenkins jenkins 0000000 0000000 neutron-fwaas-8.0.0/etc/oslo-config-generator/ 0000775 0005670 0005671 00000000000 12701410073 022422 5 ustar jenkins jenkins 0000000 0000000 neutron-fwaas-8.0.0/etc/oslo-config-generator/fwaas_driver.ini 0000664 0005670 0005671 00000000140 12701407720 025577 0 ustar jenkins jenkins 0000000 0000000 [DEFAULT]
output_file = etc/fwaas_driver.ini.sample
wrap_width = 79
namespace = firewall.agent
neutron-fwaas-8.0.0/etc/README.txt 0000664 0005670 0005671 00000000475 12701407720 017730 0 ustar jenkins jenkins 0000000 0000000 To generate the sample neutron-fwaas configuration files, run the following
command from the top level of the neutron-fwaas directory:
tox -e genconfig
If a 'tox' environment is unavailable, then you can run the following script
instead to generate the configuration files:
./tools/generate_config_file_samples.sh
neutron-fwaas-8.0.0/babel.cfg 0000664 0005670 0005671 00000000021 12701407720 017170 0 ustar jenkins jenkins 0000000 0000000 [python: **.py]
neutron-fwaas-8.0.0/.coveragerc 0000664 0005670 0005671 00000000151 12701407720 017567 0 ustar jenkins jenkins 0000000 0000000 [run]
branch = True
source = neutron_fwaas
# omit = neutron_fwaas/tests/*
[report]
ignore_errors = True
neutron-fwaas-8.0.0/setup.cfg 0000664 0005670 0005671 00000003454 12701410073 017273 0 ustar jenkins jenkins 0000000 0000000 [metadata]
name = neutron-fwaas
summary = OpenStack Networking FWaaS
description-file =
README.rst
author = OpenStack
author-email = openstack-dev@lists.openstack.org
home-page = http://www.openstack.org/
classifier =
Environment :: OpenStack
Intended Audience :: Information Technology
Intended Audience :: System Administrators
License :: OSI Approved :: Apache Software License
Operating System :: POSIX :: Linux
Programming Language :: Python
Programming Language :: Python :: 2
Programming Language :: Python :: 2.7
[files]
packages =
neutron_fwaas
[global]
setup-hooks =
pbr.hooks.setup_hook
[entry_points]
firewall_drivers =
# These are for backwards compat with Juno firewall service provider configuration values
neutron.services.firewall.drivers.linux.iptables_fwaas.IptablesFwaasDriver = neutron_fwaas.services.firewall.drivers.linux.iptables_fwaas:IptablesFwaasDriver
neutron.services.firewall.drivers.varmour.varmour_fwaas.vArmourFwaasDriver = neutron_fwaas.services.firewall.drivers.varmour.varmour_fwaas:vArmourFwaasDriver
neutron.db.alembic_migrations =
neutron-fwaas = neutron_fwaas.db.migration:alembic_migrations
tempest.test_plugins =
neutron-fwaas = neutron_fwaas.tests.tempest_plugin.plugin:NeutronFWaaSPlugin
oslo.config.opts =
firewall.agent = neutron_fwaas.opts:list_agent_opts
[build_sphinx]
all_files = 1
build-dir = doc/build
source-dir = doc/source
[extract_messages]
keywords = _ gettext ngettext l_ lazy_gettext
mapping_file = babel.cfg
output_file = neutron_fwaas/locale/neutron_fwaas.pot
[compile_catalog]
directory = neutron_fwaas/locale
domain = neutron_fwaas
[update_catalog]
domain = neutron_fwaas
output_dir = neutron_fwaas/locale
input_file = neutron_fwaas/locale/neutron_fwaas.pot
[wheel]
universal = 1
[egg_info]
tag_date = 0
tag_build =
tag_svn_revision = 0
neutron-fwaas-8.0.0/tools/ 0000775 0005670 0005671 00000000000 12701410073 016604 5 ustar jenkins jenkins 0000000 0000000 neutron-fwaas-8.0.0/tools/pretty_tox.sh 0000775 0005670 0005671 00000000305 12701407720 021367 0 ustar jenkins jenkins 0000000 0000000 #! /bin/sh
TESTRARGS=$1
exec 3>&1
status=$(exec 4>&1 >&3; (python setup.py testr --slowest --testr-args="--subunit $TESTRARGS"; echo $? >&4 ) | $(dirname $0)/subunit-trace.py -f) && exit $status
neutron-fwaas-8.0.0/tools/check_i18n.py 0000664 0005670 0005671 00000012434 12701407720 021103 0 ustar jenkins jenkins 0000000 0000000 # Copyright 2012 OpenStack Foundation
#
# 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.
from __future__ import print_function
import compiler
import imp
import os.path
import sys
def is_localized(node):
"""Check message wrapped by _()"""
if isinstance(node.parent, compiler.ast.CallFunc):
if isinstance(node.parent.node, compiler.ast.Name):
if node.parent.node.name == '_':
return True
return False
class ASTWalker(compiler.visitor.ASTVisitor):
def default(self, node, *args):
for child in node.getChildNodes():
child.parent = node
compiler.visitor.ASTVisitor.default(self, node, *args)
class Visitor(object):
def __init__(self, filename, i18n_msg_predicates,
msg_format_checkers, debug):
self.filename = filename
self.debug = debug
self.error = 0
self.i18n_msg_predicates = i18n_msg_predicates
self.msg_format_checkers = msg_format_checkers
with open(filename) as f:
self.lines = f.readlines()
def visitConst(self, node):
if not isinstance(node.value, str):
return
if is_localized(node):
for (checker, msg) in self.msg_format_checkers:
if checker(node):
print('%s:%d %s: %s Error: %s' %
(self.filename, node.lineno,
self.lines[node.lineno - 1][:-1],
checker.__name__, msg),
file=sys.stderr)
self.error = 1
return
if debug:
print('%s:%d %s: %s' %
(self.filename, node.lineno,
self.lines[node.lineno - 1][:-1],
"Pass"))
else:
for (predicate, action, msg) in self.i18n_msg_predicates:
if predicate(node):
if action == 'skip':
if debug:
print('%s:%d %s: %s' %
(self.filename, node.lineno,
self.lines[node.lineno - 1][:-1],
"Pass"))
return
elif action == 'error':
print('%s:%d %s: %s Error: %s' %
(self.filename, node.lineno,
self.lines[node.lineno - 1][:-1],
predicate.__name__, msg),
file=sys.stderr)
self.error = 1
return
elif action == 'warn':
print('%s:%d %s: %s' %
(self.filename, node.lineno,
self.lines[node.lineno - 1][:-1],
"Warn: %s" % msg))
return
print('Predicate with wrong action!', file=sys.stderr)
def is_file_in_black_list(black_list, f):
for f in black_list:
if os.path.abspath(input_file).startswith(
os.path.abspath(f)):
return True
return False
def check_i18n(input_file, i18n_msg_predicates, msg_format_checkers, debug):
input_mod = compiler.parseFile(input_file)
v = compiler.visitor.walk(input_mod,
Visitor(input_file,
i18n_msg_predicates,
msg_format_checkers,
debug),
ASTWalker())
return v.error
if __name__ == '__main__':
input_path = sys.argv[1]
cfg_path = sys.argv[2]
try:
cfg_mod = imp.load_source('', cfg_path)
except Exception:
print("Load cfg module failed", file=sys.stderr)
sys.exit(1)
i18n_msg_predicates = cfg_mod.i18n_msg_predicates
msg_format_checkers = cfg_mod.msg_format_checkers
black_list = cfg_mod.file_black_list
debug = False
if len(sys.argv) > 3:
if sys.argv[3] == '-d':
debug = True
if os.path.isfile(input_path):
sys.exit(check_i18n(input_path,
i18n_msg_predicates,
msg_format_checkers,
debug))
error = 0
for dirpath, dirs, files in os.walk(input_path):
for f in files:
if not f.endswith('.py'):
continue
input_file = os.path.join(dirpath, f)
if is_file_in_black_list(black_list, input_file):
continue
if check_i18n(input_file,
i18n_msg_predicates,
msg_format_checkers,
debug):
error = 1
sys.exit(error)
neutron-fwaas-8.0.0/tools/subunit-trace.py 0000775 0005670 0005671 00000024544 12701407720 021764 0 ustar jenkins jenkins 0000000 0000000 #!/usr/bin/env python
# Copyright 2014 Hewlett-Packard Development Company, L.P.
# Copyright 2014 Samsung Electronics
# All Rights Reserved.
#
# 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.
"""Trace a subunit stream in reasonable detail and high accuracy."""
import argparse
import functools
import os
import re
import sys
import mimeparse
import subunit
import testtools
DAY_SECONDS = 60 * 60 * 24
FAILS = []
RESULTS = {}
class Starts(testtools.StreamResult):
def __init__(self, output):
super(Starts, self).__init__()
self._output = output
def startTestRun(self):
self._neednewline = False
self._emitted = set()
def status(self, test_id=None, test_status=None, test_tags=None,
runnable=True, file_name=None, file_bytes=None, eof=False,
mime_type=None, route_code=None, timestamp=None):
super(Starts, self).status(
test_id, test_status,
test_tags=test_tags, runnable=runnable, file_name=file_name,
file_bytes=file_bytes, eof=eof, mime_type=mime_type,
route_code=route_code, timestamp=timestamp)
if not test_id:
if not file_bytes:
return
if not mime_type or mime_type == 'test/plain;charset=utf8':
mime_type = 'text/plain; charset=utf-8'
primary, sub, parameters = mimeparse.parse_mime_type(mime_type)
content_type = testtools.content_type.ContentType(
primary, sub, parameters)
content = testtools.content.Content(
content_type, lambda: [file_bytes])
text = content.as_text()
if text and text[-1] not in '\r\n':
self._neednewline = True
self._output.write(text)
elif test_status == 'inprogress' and test_id not in self._emitted:
if self._neednewline:
self._neednewline = False
self._output.write('\n')
worker = ''
for tag in test_tags or ():
if tag.startswith('worker-'):
worker = '(' + tag[7:] + ') '
if timestamp:
timestr = timestamp.isoformat()
else:
timestr = ''
self._output.write('%s: %s%s [start]\n' %
(timestr, worker, test_id))
self._emitted.add(test_id)
def cleanup_test_name(name, strip_tags=True, strip_scenarios=False):
"""Clean up the test name for display.
By default we strip out the tags in the test because they don't help us
in identifying the test that is run to it's result.
Make it possible to strip out the test scenarios information (not to
be confused with tempest scenarios) however that's often needed to
identify generated negative tests.
"""
if strip_tags:
tags_start = name.find('[')
tags_end = name.find(']')
if tags_start > 0 and tags_end > tags_start:
newname = name[:tags_start]
newname += name[tags_end + 1:]
name = newname
if strip_scenarios:
tags_start = name.find('(')
tags_end = name.find(')')
if tags_start > 0 and tags_end > tags_start:
newname = name[:tags_start]
newname += name[tags_end + 1:]
name = newname
return name
def get_duration(timestamps):
start, end = timestamps
if not start or not end:
duration = ''
else:
delta = end - start
duration = '%d.%06ds' % (
delta.days * DAY_SECONDS + delta.seconds, delta.microseconds)
return duration
def find_worker(test):
for tag in test['tags']:
if tag.startswith('worker-'):
return int(tag[7:])
return 'NaN'
# Print out stdout/stderr if it exists, always
def print_attachments(stream, test, all_channels=False):
"""Print out subunit attachments.
Print out subunit attachments that contain content. This
runs in 2 modes, one for successes where we print out just stdout
and stderr, and an override that dumps all the attachments.
"""
channels = ('stdout', 'stderr')
for name, detail in test['details'].items():
# NOTE(sdague): the subunit names are a little crazy, and actually
# are in the form pythonlogging:'' (with the colon and quotes)
name = name.split(':')[0]
if detail.content_type.type == 'test':
detail.content_type.type = 'text'
if (all_channels or name in channels) and detail.as_text():
title = "Captured %s:" % name
stream.write("\n%s\n%s\n" % (title, ('~' * len(title))))
# indent attachment lines 4 spaces to make them visually
# offset
for line in detail.as_text().split('\n'):
stream.write(" %s\n" % line)
def show_outcome(stream, test, print_failures=False, failonly=False):
global RESULTS
status = test['status']
# TODO(sdague): ask lifeless why on this?
if status == 'exists':
return
worker = find_worker(test)
name = cleanup_test_name(test['id'])
duration = get_duration(test['timestamps'])
if worker not in RESULTS:
RESULTS[worker] = []
RESULTS[worker].append(test)
# don't count the end of the return code as a fail
if name == 'process-returncode':
return
if status == 'fail':
FAILS.append(test)
stream.write('{%s} %s [%s] ... FAILED\n' % (
worker, name, duration))
if not print_failures:
print_attachments(stream, test, all_channels=True)
elif not failonly:
if status == 'success':
stream.write('{%s} %s [%s] ... ok\n' % (
worker, name, duration))
print_attachments(stream, test)
elif status == 'skip':
stream.write('{%s} %s ... SKIPPED: %s\n' % (
worker, name, test['details']['reason'].as_text()))
else:
stream.write('{%s} %s [%s] ... %s\n' % (
worker, name, duration, test['status']))
if not print_failures:
print_attachments(stream, test, all_channels=True)
stream.flush()
def print_fails(stream):
"""Print summary failure report.
Currently unused, however there remains debate on inline vs. at end
reporting, so leave the utility function for later use.
"""
if not FAILS:
return
stream.write("\n==============================\n")
stream.write("Failed %s tests - output below:" % len(FAILS))
stream.write("\n==============================\n")
for f in FAILS:
stream.write("\n%s\n" % f['id'])
stream.write("%s\n" % ('-' * len(f['id'])))
print_attachments(stream, f, all_channels=True)
stream.write('\n')
def count_tests(key, value):
count = 0
for k, v in RESULTS.items():
for item in v:
if key in item:
if re.search(value, item[key]):
count += 1
return count
def run_time():
runtime = 0.0
for k, v in RESULTS.items():
for test in v:
runtime += float(get_duration(test['timestamps']).strip('s'))
return runtime
def worker_stats(worker):
tests = RESULTS[worker]
num_tests = len(tests)
delta = tests[-1]['timestamps'][1] - tests[0]['timestamps'][0]
return num_tests, delta
def print_summary(stream):
stream.write("\n======\nTotals\n======\n")
stream.write("Run: %s in %s sec.\n" % (count_tests('status', '.*'),
run_time()))
stream.write(" - Passed: %s\n" % count_tests('status', 'success'))
stream.write(" - Skipped: %s\n" % count_tests('status', 'skip'))
stream.write(" - Failed: %s\n" % count_tests('status', 'fail'))
# we could have no results, especially as we filter out the process-codes
if RESULTS:
stream.write("\n==============\nWorker Balance\n==============\n")
for w in range(max(RESULTS.keys()) + 1):
if w not in RESULTS:
stream.write(
" - WARNING: missing Worker %s! "
"Race in testr accounting.\n" % w)
else:
num, time = worker_stats(w)
stream.write(" - Worker %s (%s tests) => %ss\n" %
(w, num, time))
def parse_args():
parser = argparse.ArgumentParser()
parser.add_argument('--no-failure-debug', '-n', action='store_true',
dest='print_failures', help='Disable printing failure '
'debug information in realtime')
parser.add_argument('--fails', '-f', action='store_true',
dest='post_fails', help='Print failure debug '
'information after the stream is proccesed')
parser.add_argument('--failonly', action='store_true',
dest='failonly', help="Don't print success items",
default=(
os.environ.get('TRACE_FAILONLY', False)
is not False))
return parser.parse_args()
def main():
args = parse_args()
stream = subunit.ByteStreamToStreamResult(
sys.stdin, non_subunit_name='stdout')
starts = Starts(sys.stdout)
outcomes = testtools.StreamToDict(
functools.partial(show_outcome, sys.stdout,
print_failures=args.print_failures,
failonly=args.failonly
))
summary = testtools.StreamSummary()
result = testtools.CopyStreamResult([starts, outcomes, summary])
result.startTestRun()
try:
stream.run(result)
finally:
result.stopTestRun()
if count_tests('status', '.*') == 0:
print("The test run didn't actually run any tests")
return 1
if args.post_fails:
print_fails(sys.stdout)
print_summary(sys.stdout)
return (0 if summary.wasSuccessful() else 1)
if __name__ == '__main__':
sys.exit(main())
neutron-fwaas-8.0.0/tools/generate_config_file_samples.sh 0000775 0005670 0005671 00000001440 12701407720 025011 0 ustar jenkins jenkins 0000000 0000000 #!/bin/sh
#
# 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.
set -e
GEN_CMD=oslo-config-generator
if ! type "$GEN_CMD" > /dev/null; then
echo "ERROR: $GEN_CMD not installed on the system."
exit 1
fi
for file in `ls etc/oslo-config-generator/*`; do
$GEN_CMD --config-file=$file
done
set -x
neutron-fwaas-8.0.0/tools/check_i18n_test_case.txt 0000664 0005670 0005671 00000002645 12701407720 023327 0 ustar jenkins jenkins 0000000 0000000 # test-case for check_i18n.py
# python check_i18n.py check_i18n.txt -d
# message format checking
# capital checking
msg = _("hello world, error")
msg = _("hello world_var, error")
msg = _('file_list xyz, pass')
msg = _("Hello world, pass")
# format specifier checking
msg = _("Hello %s world %d, error")
msg = _("Hello %s world, pass")
msg = _("Hello %(var1)s world %(var2)s, pass")
# message has been localized
# is_localized
msg = _("Hello world, pass")
msg = _("Hello world, pass") % var
LOG.debug(_('Hello world, pass'))
LOG.info(_('Hello world, pass'))
raise x.y.Exception(_('Hello world, pass'))
raise Exception(_('Hello world, pass'))
# message need be localized
# is_log_callfunc
LOG.debug('hello world, error')
LOG.debug('hello world, error' % xyz)
sys.append('hello world, warn')
# is_log_i18n_msg_with_mod
LOG.debug(_('Hello world, error') % xyz)
# default warn
msg = 'hello world, warn'
msg = 'hello world, warn' % var
# message needn't be localized
# skip only one word
msg = ''
msg = "hello,pass"
# skip dict
msg = {'hello world, pass': 1}
# skip list
msg = ["hello world, pass"]
# skip subscript
msg['hello world, pass']
# skip xml marker
msg = ", pass"
# skip sql statement
msg = "SELECT * FROM xyz WHERE hello=1, pass"
msg = "select * from xyz, pass"
# skip add statement
msg = 'hello world' + e + 'world hello, pass'
# skip doc string
"""
Hello world, pass
"""
class Msg:
pass
neutron-fwaas-8.0.0/tools/install_venv_common.py 0000664 0005670 0005671 00000013507 12701407720 023245 0 ustar jenkins jenkins 0000000 0000000 # Copyright 2013 OpenStack Foundation
# Copyright 2013 IBM Corp.
#
# 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.
"""Provides methods needed by installation script for OpenStack development
virtual environments.
Since this script is used to bootstrap a virtualenv from the system's Python
environment, it should be kept strictly compatible with Python 2.6.
Synced in from openstack-common
"""
from __future__ import print_function
import optparse
import os
import subprocess
import sys
class InstallVenv(object):
def __init__(self, root, venv, requirements,
test_requirements, py_version,
project):
self.root = root
self.venv = venv
self.requirements = requirements
self.test_requirements = test_requirements
self.py_version = py_version
self.project = project
def die(self, message, *args):
print(message % args, file=sys.stderr)
sys.exit(1)
def check_python_version(self):
if sys.version_info < (2, 6):
self.die("Need Python Version >= 2.6")
def run_command_with_code(self, cmd, redirect_output=True,
check_exit_code=True):
"""Runs a command in an out-of-process shell.
Returns the output of that command. Working directory is self.root.
"""
if redirect_output:
stdout = subprocess.PIPE
else:
stdout = None
proc = subprocess.Popen(cmd, cwd=self.root, stdout=stdout)
output = proc.communicate()[0]
if check_exit_code and proc.returncode != 0:
self.die('Command "%s" failed.\n%s', ' '.join(cmd), output)
return (output, proc.returncode)
def run_command(self, cmd, redirect_output=True, check_exit_code=True):
return self.run_command_with_code(cmd, redirect_output,
check_exit_code)[0]
def get_distro(self):
if (os.path.exists('/etc/fedora-release') or
os.path.exists('/etc/redhat-release')):
return Fedora(
self.root, self.venv, self.requirements,
self.test_requirements, self.py_version, self.project)
else:
return Distro(
self.root, self.venv, self.requirements,
self.test_requirements, self.py_version, self.project)
def check_dependencies(self):
self.get_distro().install_virtualenv()
def create_virtualenv(self, no_site_packages=True):
"""Creates the virtual environment and installs PIP.
Creates the virtual environment and installs PIP only into the
virtual environment.
"""
if not os.path.isdir(self.venv):
print('Creating venv...', end=' ')
if no_site_packages:
self.run_command(['virtualenv', '-q', '--no-site-packages',
self.venv])
else:
self.run_command(['virtualenv', '-q', self.venv])
print('done.')
else:
print("venv already exists...")
pass
def pip_install(self, *args):
self.run_command(['tools/with_venv.sh',
'pip', 'install', '--upgrade'] + list(args),
redirect_output=False)
def install_dependencies(self):
print('Installing dependencies with pip (this can take a while)...')
# First things first, make sure our venv has the latest pip and
# setuptools and pbr
self.pip_install('pip>=1.4')
self.pip_install('setuptools')
self.pip_install('pbr')
self.pip_install('-r', self.requirements, '-r', self.test_requirements)
def parse_args(self, argv):
"""Parses command-line arguments."""
parser = optparse.OptionParser()
parser.add_option('-n', '--no-site-packages',
action='store_true',
help="Do not inherit packages from global Python "
"install.")
return parser.parse_args(argv[1:])[0]
class Distro(InstallVenv):
def check_cmd(self, cmd):
return bool(self.run_command(['which', cmd],
check_exit_code=False).strip())
def install_virtualenv(self):
if self.check_cmd('virtualenv'):
return
if self.check_cmd('easy_install'):
print('Installing virtualenv via easy_install...', end=' ')
if self.run_command(['easy_install', 'virtualenv']):
print('Succeeded')
return
else:
print('Failed')
self.die('ERROR: virtualenv not found.\n\n%s development'
' requires virtualenv, please install it using your'
' favorite package management tool' % self.project)
class Fedora(Distro):
"""This covers all Fedora-based distributions.
Includes: Fedora, RHEL, CentOS, Scientific Linux
"""
def check_pkg(self, pkg):
return self.run_command_with_code(['rpm', '-q', pkg],
check_exit_code=False)[1] == 0
def install_virtualenv(self):
if self.check_cmd('virtualenv'):
return
if not self.check_pkg('python-virtualenv'):
self.die("Please install 'python-virtualenv'.")
super(Fedora, self).install_virtualenv()
neutron-fwaas-8.0.0/tools/install_venv.py 0000664 0005670 0005671 00000004400 12701407720 021665 0 ustar jenkins jenkins 0000000 0000000 #!/usr/bin/env python
# Copyright 2010 United States Government as represented by the
# Administrator of the National Aeronautics and Space Administration.
# All Rights Reserved.
#
# Copyright 2010 OpenStack Foundation.
# Copyright 2013 IBM Corp.
#
# 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.
"""
Installation script for Neutron's development virtualenv
"""
from __future__ import print_function
import os
import sys
import install_venv_common as install_venv
def print_help():
help = """
Neutron development environment setup is complete.
Neutron development uses virtualenv to track and manage Python dependencies
while in development and testing.
To activate the Neutron virtualenv for the extent of your current shell
session you can run:
$ source .venv/bin/activate
Or, if you prefer, you can run commands in the virtualenv on a case by case
basis by running:
$ tools/with_venv.sh
Also, make test will automatically use the virtualenv.
"""
print(help)
def main(argv):
root = os.path.dirname(os.path.dirname(os.path.realpath(__file__)))
venv = os.path.join(root, '.venv')
pip_requires = os.path.join(root, 'requirements.txt')
test_requires = os.path.join(root, 'test-requirements.txt')
py_version = "python%s.%s" % (sys.version_info[0], sys.version_info[1])
project = 'Neutron'
install = install_venv.InstallVenv(root, venv, pip_requires, test_requires,
py_version, project)
options = install.parse_args(argv)
install.check_python_version()
install.check_dependencies()
install.create_virtualenv(no_site_packages=options.no_site_packages)
install.install_dependencies()
print_help()
if __name__ == '__main__':
main(sys.argv)
neutron-fwaas-8.0.0/tools/with_venv.sh 0000775 0005670 0005671 00000001333 12701407720 021161 0 ustar jenkins jenkins 0000000 0000000 #!/usr/bin/env bash
# Copyright 2011 OpenStack Foundation.
# All Rights Reserved.
#
# 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.
TOOLS=`dirname $0`
VENV=$TOOLS/../.venv
source $VENV/bin/activate && "$@"
neutron-fwaas-8.0.0/tools/i18n_cfg.py 0000664 0005670 0005671 00000006643 12701407720 020572 0 ustar jenkins jenkins 0000000 0000000 import compiler
import re
def is_log_callfunc(n):
"""LOG.xxx('hello %s' % xyz) and LOG('hello')"""
if isinstance(n.parent, compiler.ast.Mod):
n = n.parent
if isinstance(n.parent, compiler.ast.CallFunc):
if isinstance(n.parent.node, compiler.ast.Getattr):
if isinstance(n.parent.node.getChildNodes()[0],
compiler.ast.Name):
if n.parent.node.getChildNodes()[0].name == 'LOG':
return True
return False
def is_log_i18n_msg_with_mod(n):
"""LOG.xxx("Hello %s" % xyz) should be LOG.xxx("Hello %s", xyz)"""
if not isinstance(n.parent.parent, compiler.ast.Mod):
return False
n = n.parent.parent
if isinstance(n.parent, compiler.ast.CallFunc):
if isinstance(n.parent.node, compiler.ast.Getattr):
if isinstance(n.parent.node.getChildNodes()[0],
compiler.ast.Name):
if n.parent.node.getChildNodes()[0].name == 'LOG':
return True
return False
def is_wrong_i18n_format(n):
"""Check _('hello %s' % xyz)"""
if isinstance(n.parent, compiler.ast.Mod):
n = n.parent
if isinstance(n.parent, compiler.ast.CallFunc):
if isinstance(n.parent.node, compiler.ast.Name):
if n.parent.node.name == '_':
return True
return False
"""
Used for check message need be localized or not.
(predicate_func, action, message)
"""
i18n_msg_predicates = [
# Skip ['hello world', 1]
(lambda n: isinstance(n.parent, compiler.ast.List), 'skip', ''),
# Skip {'hellow world', 1}
(lambda n: isinstance(n.parent, compiler.ast.Dict), 'skip', ''),
# Skip msg['hello world']
(lambda n: isinstance(n.parent, compiler.ast.Subscript), 'skip', ''),
# Skip doc string
(lambda n: isinstance(n.parent, compiler.ast.Discard), 'skip', ''),
# Skip msg = "hello", in normal, message should more than one word
(lambda n: len(n.value.strip().split(' ')) <= 1, 'skip', ''),
# Skip msg = 'hello world' + vars + 'world hello'
(lambda n: isinstance(n.parent, compiler.ast.Add), 'skip', ''),
# Skip xml markers msg = ""
(lambda n: len(re.compile("").findall(n.value)) > 0, 'skip', ''),
# Skip sql statement
(lambda n: len(
re.compile("^SELECT.*FROM", flags=re.I).findall(n.value)) > 0,
'skip', ''),
# LOG.xxx()
(is_log_callfunc, 'error', 'Message must be localized'),
# _('hello %s' % xyz) should be _('hello %s') % xyz
(is_wrong_i18n_format, 'error',
("Message format was wrong, _('hello %s' % xyz) "
"should be _('hello %s') % xyz")),
# default
(lambda n: True, 'warn', 'Message might need localized')
]
"""
Used for checking message format. (checker_func, message)
"""
msg_format_checkers = [
# If message contain more than on format specifier, it should use
# mapping key
(lambda n: len(re.compile("%[bcdeEfFgGnosxX]").findall(n.value)) > 1,
"The message shouldn't contain more than one format specifier"),
# Check capital
(lambda n: n.value.split(' ')[0].count('_') == 0 and
n.value[0].isalpha() and
n.value[0].islower(),
"First letter must be capital"),
(is_log_i18n_msg_with_mod,
'LOG.xxx("Hello %s" % xyz) should be LOG.xxx("Hello %s", xyz)')
]
file_black_list = ["./neutron/tests/unit",
"./neutron/openstack",
"./neutron/plugins/bigswitch/tests"]
neutron-fwaas-8.0.0/tools/clean.sh 0000775 0005670 0005671 00000000304 12701407720 020227 0 ustar jenkins jenkins 0000000 0000000 #!/usr/bin/env bash
rm -rf ./*.deb ./*.tar.gz ./*.dsc ./*.changes
rm -rf */*.deb
rm -rf ./plugins/**/build/ ./plugins/**/dist
rm -rf ./plugins/**/lib/neutron_*_plugin.egg-info ./plugins/neutron-*
neutron-fwaas-8.0.0/tools/tox_install.sh 0000775 0005670 0005671 00000002470 12701407721 021514 0 ustar jenkins jenkins 0000000 0000000 #!/bin/sh
# Many of neutron's repos suffer from the problem of depending on neutron,
# but it not existing on pypi.
# This wrapper for tox's package installer will use the existing package
# if it exists, else use zuul-cloner if that program exists, else grab it
# from neutron master via a hard-coded URL. That last case should only
# happen with devs running unit tests locally.
ZUUL_CLONER=/usr/zuul-env/bin/zuul-cloner
neutron_installed=$(echo "import neutron" | python 2>/dev/null ; echo $?)
BRANCH_NAME=stable/mitaka
set -e
CONSTRAINTS_FILE=$1
shift
install_cmd="pip install"
if [ $CONSTRAINTS_FILE != "unconstrained" ]; then
install_cmd="$install_cmd -c$CONSTRAINTS_FILE"
fi
if [ $neutron_installed -eq 0 ]; then
echo "ALREADY INSTALLED" > /tmp/tox_install.txt
echo "Neutron already installed; using existing package"
elif [ -x "$ZUUL_CLONER" ]; then
echo "ZUUL CLONER" > /tmp/tox_install.txt
cwd=$(/bin/pwd)
cd /tmp
$ZUUL_CLONER --cache-dir \
/opt/git \
--branch $BRANCH_NAME \
git://git.openstack.org \
openstack/neutron
cd openstack/neutron
$install_cmd -e .
cd "$cwd"
else
echo "PIP HARDCODE" > /tmp/tox_install.txt
$install_cmd -U -egit+https://git.openstack.org/openstack/neutron@$BRANCH_NAME#egg=neutron
fi
$install_cmd -U $*
exit $?
neutron-fwaas-8.0.0/tools/check_unit_test_structure.sh 0000775 0005670 0005671 00000003075 12701407720 024450 0 ustar jenkins jenkins 0000000 0000000 #!/usr/bin/env bash
# This script identifies the unit test modules that do not correspond
# directly with a module in the code tree. See TESTING.rst for the
# intended structure.
neutron_path=$(cd "$(dirname "$0")/.." && pwd)
base_test_path=neutron_fwaas/tests/unit
test_path=$neutron_path/$base_test_path
test_files=$(find ${test_path} -iname 'test_*.py')
ignore_regexes=(
"^plugins.*$"
)
error_count=0
ignore_count=0
total_count=0
for test_file in ${test_files[@]}; do
relative_path=${test_file#$test_path/}
expected_path=$(dirname $neutron_path/neutron_fwaas/$relative_path)
test_filename=$(basename "$test_file")
expected_filename=${test_filename#test_}
# Module filename (e.g. foo/bar.py -> foo/test_bar.py)
filename=$expected_path/$expected_filename
# Package dir (e.g. foo/ -> test_foo.py)
package_dir=${filename%.py}
if [ ! -f "$filename" ] && [ ! -d "$package_dir" ]; then
for ignore_regex in ${ignore_regexes[@]}; do
if [[ "$relative_path" =~ $ignore_regex ]]; then
((ignore_count++))
continue 2
fi
done
echo "Unexpected test file: $base_test_path/$relative_path"
((error_count++))
fi
((total_count++))
done
if [ "$ignore_count" -ne 0 ]; then
echo "$ignore_count unmatched test modules were ignored"
fi
if [ "$error_count" -eq 0 ]; then
echo 'Success! All test modules match targets in the code tree.'
exit 0
else
echo "Failure! $error_count of $total_count test modules do not match targets in the code tree."
exit 1
fi
neutron-fwaas-8.0.0/doc/ 0000775 0005670 0005671 00000000000 12701410073 016211 5 ustar jenkins jenkins 0000000 0000000 neutron-fwaas-8.0.0/doc/source/ 0000775 0005670 0005671 00000000000 12701410073 017511 5 ustar jenkins jenkins 0000000 0000000 neutron-fwaas-8.0.0/doc/source/index.rst 0000664 0005670 0005671 00000000253 12701407720 021357 0 ustar jenkins jenkins 0000000 0000000 .. documentation master file
====
Main
====
.. toctree::
:glob:
:maxdepth: 1
main/*
==================
Indices and tables
==================
* :ref:`search`
neutron-fwaas-8.0.0/doc/source/conf.py 0000664 0005670 0005671 00000017535 12701407720 021030 0 ustar jenkins jenkins 0000000 0000000 # -*- coding: utf-8 -*-
# Copyright (c) 2010 OpenStack Foundation.
#
# 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.
#
# Keystone documentation build configuration file, created by
# sphinx-quickstart on Tue May 18 13:50:15 2010.
#
# This file is execfile()'d with the current directory set to it's containing
# dir.
#
# Note that not all possible configuration values are present in this
# autogenerated file.
#
# All configuration values have a default; values that are commented out
# serve to show the default.
import os
import subprocess
import sys
# If extensions (or modules to document with autodoc) are in another directory,
# add these directories to sys.path here. If the directory is relative to the
# documentation root, use os.path.abspath to make it absolute, like shown here.
BASE_DIR = os.path.dirname(os.path.abspath(__file__))
ROOT_DIR = os.path.abspath(os.path.join(BASE_DIR, "..", ".."))
sys.path.insert(0, ROOT_DIR)
# -- General configuration ---------------------------------------------------
# Add any Sphinx extension module names here, as strings. They can be
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
extensions = ['sphinx.ext.autodoc',
'sphinx.ext.coverage',
'sphinx.ext.ifconfig',
'sphinx.ext.graphviz',
'sphinx.ext.todo',
'oslosphinx']
todo_include_todos = True
# Add any paths that contain templates here, relative to this directory.
templates_path = []
if os.getenv('HUDSON_PUBLISH_DOCS'):
templates_path = ['_ga', '_templates']
else:
templates_path = ['_templates']
# The suffix of source filenames.
source_suffix = '.rst'
# The encoding of source files.
#source_encoding = 'utf-8'
# The master toctree document.
master_doc = 'index'
# General information about the project.
project = u'Neutron FWaaS'
copyright = u'2011-present, OpenStack Foundation.'
# The version info for the project you're documenting, acts as replacement for
# |version| and |release|, also used in various other places throughout the
# built documents.
#
# Version info
from neutron_fwaas.version import version_info as neutron_fwaas_version
release = neutron_fwaas_version.release_string()
# The short X.Y version.
version = neutron_fwaas_version.version_string()
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
#language = None
# There are two options for replacing |today|: either, you set today to some
# non-false value, then it is used:
#today = ''
# Else, today_fmt is used as the format for a strftime call.
#today_fmt = '%B %d, %Y'
# List of documents that shouldn't be included in the build.
# unused_docs = []
# List of directories, relative to source directory, that shouldn't be searched
# for source files.
exclude_trees = []
# The reST default role (for this markup: `text`) to use for all documents.
#default_role = None
# If true, '()' will be appended to :func: etc. cross-reference text.
#add_function_parentheses = True
# If true, the current module name will be prepended to all description
# unit titles (such as .. function::).
#add_module_names = True
# If true, sectionauthor and moduleauthor directives will be shown in the
# output. They are ignored by default.
show_authors = True
# The name of the Pygments (syntax highlighting) style to use.
pygments_style = 'sphinx'
# A list of ignored prefixes for module index sorting.
modindex_common_prefix = ['neutron_fwaas.']
# -- Options for man page output --------------------------------------------
# Grouping the document tree for man pages.
# List of tuples 'sourcefile', 'target', u'title', u'Authors name', 'manual'
#man_pages = [
# ('man/neutron-server', 'neutron-server', u'Neutron Server',
# [u'OpenStack'], 1)
#]
# -- Options for HTML output -------------------------------------------------
# The theme to use for HTML and HTML Help pages. Major themes that come with
# Sphinx are currently 'default' and 'sphinxdoc'.
# html_theme_path = ["."]
# html_theme = '_theme'
# Theme options are theme-specific and customize the look and feel of a theme
# further. For a list of options available for each theme, see the
# documentation.
#html_theme_options = {}
# Add any paths that contain custom themes here, relative to this directory.
#html_theme_path = ['_theme']
# The name for this set of Sphinx documents. If None, it defaults to
# " v documentation".
#html_title = None
# A shorter title for the navigation bar. Default is the same as html_title.
#html_short_title = None
# The name of an image file (relative to this directory) to place at the top
# of the sidebar.
#html_logo = None
# The name of an image file (within the static path) to use as favicon of the
# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
# pixels large.
#html_favicon = None
# Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files,
# so a file named "default.css" will overwrite the builtin "default.css".
# html_static_path = ['_static']
# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
# using the given strftime format.
#html_last_updated_fmt = '%b %d, %Y'
git_cmd = ["git", "log", "--pretty=format:'%ad, commit %h'", "--date=local",
"-n1"]
html_last_updated_fmt = subprocess.Popen(
git_cmd, stdout=subprocess.PIPE).communicate()[0]
# If true, SmartyPants will be used to convert quotes and dashes to
# typographically correct entities.
#html_use_smartypants = True
# Custom sidebar templates, maps document names to template names.
#html_sidebars = {}
# Additional templates that should be rendered to pages, maps page names to
# template names.
#html_additional_pages = {}
# If false, no module index is generated.
#html_use_modindex = True
# If false, no index is generated.
#html_use_index = True
# If true, the index is split into individual pages for each letter.
#html_split_index = False
# If true, links to the reST sources are added to the pages.
#html_show_sourcelink = True
# If true, an OpenSearch description file will be output, and all pages will
# contain a tag referring to it. The value of this option must be the
# base URL from which the finished HTML is served.
#html_use_opensearch = ''
# If nonempty, this is the file name suffix for HTML files (e.g. ".xhtml").
#html_file_suffix = ''
# Output file base name for HTML help builder.
#htmlhelp_basename = 'neutrondoc'
# -- Options for LaTeX output ------------------------------------------------
# The paper size ('letter' or 'a4').
#latex_paper_size = 'letter'
# The font size ('10pt', '11pt' or '12pt').
#latex_font_size = '10pt'
# Grouping the document tree into LaTeX files. List of tuples
# (source start file, target name, title, author,
# documentclass [howto/manual]).
#latex_documents = [
# ('index', 'Neutron.tex', u'Neutron Documentation',
# u'Neutron development team', 'manual'),
#]
# The name of an image file (relative to this directory) to place at the top of
# the title page.
#latex_logo = None
# For "manual" documents, if this is true, then toplevel headings are parts,
# not chapters.
#latex_use_parts = False
# Additional stuff for the LaTeX preamble.
#latex_preamble = ''
# Documents to append as an appendix to all manuals.
#latex_appendices = []
# If false, no module index is generated.
#latex_use_modindex = True
neutron-fwaas-8.0.0/neutron_fwaas/ 0000775 0005670 0005671 00000000000 12701410073 020317 5 ustar jenkins jenkins 0000000 0000000 neutron-fwaas-8.0.0/neutron_fwaas/tests/ 0000775 0005670 0005671 00000000000 12701410073 021461 5 ustar jenkins jenkins 0000000 0000000 neutron-fwaas-8.0.0/neutron_fwaas/tests/__init__.py 0000664 0005670 0005671 00000000000 12701407720 023565 0 ustar jenkins jenkins 0000000 0000000 neutron-fwaas-8.0.0/neutron_fwaas/tests/contrib/ 0000775 0005670 0005671 00000000000 12701410073 023121 5 ustar jenkins jenkins 0000000 0000000 neutron-fwaas-8.0.0/neutron_fwaas/tests/contrib/README 0000664 0005670 0005671 00000000226 12701407720 024006 0 ustar jenkins jenkins 0000000 0000000 The files in this directory are intended for use by the
infra jobs that run the various functional test
suite in the gate for the neutron-fwaas repo.
neutron-fwaas-8.0.0/neutron_fwaas/tests/contrib/filters.template 0000664 0005670 0005671 00000001374 12701407720 026340 0 ustar jenkins jenkins 0000000 0000000 # neutron-rootwrap command filters to support functional testing. It
# is NOT intended to be used outside of a test environment.
#
# This file should be owned by (and only-writeable by) the root user
[Filters]
# '$BASE_PATH' is intended to be replaced with the expected tox path
# (e.g. /opt/stack/new/neutron/.tox/dsvm-functional) by the neutron
# functional jenkins job. This ensures that tests can kill the
# processes that they launch with their containing tox environment's
# python.
kill_tox_python: KillFilter, root, $BASE_PATH/bin/python, -9
# enable ping from namespace
ping_filter: CommandFilter, ping, root
# enable curl from namespace
curl_filter: CommandFilter, curl, root
tee_filter: CommandFilter, tee, root
tee_kill: KillFilter, root, tee, -9
neutron-fwaas-8.0.0/neutron_fwaas/tests/contrib/gate_hook.sh 0000775 0005670 0005671 00000005160 12701407720 025427 0 ustar jenkins jenkins 0000000 0000000 #!/bin/bash
set -ex
# Below variables are set to exceute this script
IS_GATE=${IS_GATE:-False}
INSTALL_MYSQL_ONLY=${INSTALL_MYSQL_ONLY:-True}
CONTRIB_DIR="$BASE/new/neutron-fwaas/neutron_fwaas/tests/contrib"
$BASE/new/devstack-gate/devstack-vm-gate.sh
# Add a rootwrap filter to support test-only
# configuration (e.g. a KillFilter for processes that
# use the python installed in a tox env).
FUNC_FILTER=$CONTRIB_DIR/filters.template
sed -e "s+\$BASE_PATH+$BASE/new/neutron-fwaas/.tox/dsvm-functional+" \
$FUNC_FILTER | sudo tee /etc/neutron/rootwrap.d/functional.filters > /dev/null
# Use devstack functions to install mysql and psql servers
TOP_DIR=$BASE/new/devstack
source $TOP_DIR/functions
source $TOP_DIR/inc/meta-config
source $TOP_DIR/stackrc
source $TOP_DIR/lib/database
source $TOP_DIR/localrc
# Install_databases [install_pg]
# Tweak the script accordingly if we need psql in future
function _install_databases {
local install_pg=${1:-True}
echo_summary "Installing databases"
# Avoid attempting to configure the db if it appears to already
# have run. The setup as currently defined is not idempotent.
if mysql openstack_citest > /dev/null 2>&1 < /dev/null; then
echo_summary "DB config appears to be complete, skipping."
return 0
fi
enable_service mysql
initialize_database_backends
install_database
configure_database_mysql
if [[ "$install_pg" == "True" ]]; then
enable_service postgresql
initialize_database_backends
install_database
configure_database_postgresql
fi
# Set up the 'openstack_citest' user and database in each backend
tmp_dir=$(mktemp -d)
trap "rm -rf $tmp_dir" EXIT
cat << EOF > $tmp_dir/mysql.sql
CREATE DATABASE openstack_citest;
CREATE USER 'openstack_citest'@'localhost' IDENTIFIED BY 'openstack_citest';
CREATE USER 'openstack_citest' IDENTIFIED BY 'openstack_citest';
GRANT ALL PRIVILEGES ON *.* TO 'openstack_citest'@'localhost';
GRANT ALL PRIVILEGES ON *.* TO 'openstack_citest';
FLUSH PRIVILEGES;
EOF
/usr/bin/mysql -u root < $tmp_dir/mysql.sql
if [[ "$install_pg" == "True" ]]; then
cat << EOF > $tmp_dir/postgresql.sql
CREATE USER openstack_citest WITH CREATEDB LOGIN PASSWORD 'openstack_citest';
CREATE DATABASE openstack_citest WITH OWNER openstack_citest;
EOF
# User/group postgres needs to be given access to tmp_dir
setfacl -m g:postgres:rwx $tmp_dir
sudo -u postgres /usr/bin/psql --file=$tmp_dir/postgresql.sql
fi
}
if [[ "$IS_GATE" != "True" ]]; then
if [[ "$INSTALL_MYSQL_ONLY" == "True" ]]; then
_install_databases nopg
fi
fi neutron-fwaas-8.0.0/neutron_fwaas/tests/contrib/post_test_hook.sh 0000775 0005670 0005671 00000002146 12701407720 026534 0 ustar jenkins jenkins 0000000 0000000 #!/bin/bash
set -xe
NEUTRON_DIR="$BASE/new/neutron-fwaas"
TEMPEST_DIR="$BASE/new/tempest"
SCRIPTS_DIR="/usr/os-testr-env/bin"
function generate_testr_results {
# Give job user rights to access tox logs
sudo -H -u $owner chmod o+rw .
sudo -H -u $owner chmod o+rw -R .testrepository
if [ -f ".testrepository/0" ] ; then
.tox/dsvm-functional/bin/subunit-1to2 < .testrepository/0 > ./testrepository.subunit
$SCRIPTS_DIR/subunit2html ./testrepository.subunit testr_results.html
gzip -9 ./testrepository.subunit
gzip -9 ./testr_results.html
sudo mv ./*.gz /opt/stack/logs/
fi
}
function dsvm_functional_prep_func {
:
}
owner=stack
prep_func="dsvm_functional_prep_func"
# Set owner permissions according to job's requirements.
cd $NEUTRON_DIR
sudo chown -R $owner:stack $NEUTRON_DIR
# Prep the environment according to job's requirements.
$prep_func
# Run tests
echo "Running neutron dsvm-functional test suite"
set +e
sudo -H -u $owner tox -e dsvm-functional
testr_exit_code=$?
set -e
# Collect and parse results
generate_testr_results
exit $testr_exit_code
neutron-fwaas-8.0.0/neutron_fwaas/tests/base.py 0000664 0005670 0005671 00000001575 12701407720 022762 0 ustar jenkins jenkins 0000000 0000000 # Copyright 2014 OpenStack Foundation.
# All Rights Reserved.
#
# 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.
#
from neutron.tests import base as n_base
from neutron.tests.unit.db import test_db_base_plugin_v2 as test_db_plugin
class BaseTestCase(n_base.BaseTestCase):
pass
class NeutronDbPluginV2TestCase(test_db_plugin.NeutronDbPluginV2TestCase):
pass
neutron-fwaas-8.0.0/neutron_fwaas/tests/tempest_plugin/ 0000775 0005670 0005671 00000000000 12701410073 024520 5 ustar jenkins jenkins 0000000 0000000 neutron-fwaas-8.0.0/neutron_fwaas/tests/tempest_plugin/plugin.py 0000664 0005670 0005671 00000002316 12701407720 026377 0 ustar jenkins jenkins 0000000 0000000 # Copyright (c) 2015 Midokura SARL
# All Rights Reserved.
#
# 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.
import os
from tempest.test_discover import plugins
class NeutronFWaaSPlugin(plugins.TempestPlugin):
def get_opt_lists(self):
return []
def load_tests(self):
this_dir = os.path.dirname(os.path.abspath(__file__))
# top_level_dir = $(this_dir)/../../..
d = os.path.split(this_dir)[0]
d = os.path.split(d)[0]
top_level_dir = os.path.split(d)[0]
test_dir = os.path.join(top_level_dir,
'neutron_fwaas/tests/tempest_plugin/tests')
return (test_dir, top_level_dir)
def register_opts(self, conf):
return
neutron-fwaas-8.0.0/neutron_fwaas/tests/tempest_plugin/tests/ 0000775 0005670 0005671 00000000000 12701410073 025662 5 ustar jenkins jenkins 0000000 0000000 neutron-fwaas-8.0.0/neutron_fwaas/tests/tempest_plugin/tests/__init__.py 0000664 0005670 0005671 00000000000 12701407720 027766 0 ustar jenkins jenkins 0000000 0000000 neutron-fwaas-8.0.0/neutron_fwaas/tests/tempest_plugin/tests/fwaas_client.py 0000664 0005670 0005671 00000011345 12701407720 030704 0 ustar jenkins jenkins 0000000 0000000 # Copyright (c) 2015 Midokura SARL
# All Rights Reserved.
#
# 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.
import time
from tempest import config
from tempest import exceptions
from tempest.lib.common.utils import data_utils
from tempest.lib import exceptions as lib_exc
from neutron.plugins.common import constants as p_const
from neutron_fwaas.tests.tempest_plugin.services import client
CONF = config.CONF
class FWaaSClientMixin(object):
@classmethod
def resource_setup(cls):
super(FWaaSClientMixin, cls).resource_setup()
manager = cls.manager
cls.firewalls_client = client.FirewallsClient(
manager.auth_provider,
CONF.network.catalog_type,
CONF.network.region or CONF.identity.region,
endpoint_type=CONF.network.endpoint_type,
build_interval=CONF.network.build_interval,
build_timeout=CONF.network.build_timeout,
**manager.default_params)
cls.firewall_policies_client = client.FirewallPoliciesClient(
manager.auth_provider,
CONF.network.catalog_type,
CONF.network.region or CONF.identity.region,
endpoint_type=CONF.network.endpoint_type,
build_interval=CONF.network.build_interval,
build_timeout=CONF.network.build_timeout,
**manager.default_params)
cls.firewall_rules_client = client.FirewallRulesClient(
manager.auth_provider,
CONF.network.catalog_type,
CONF.network.region or CONF.identity.region,
endpoint_type=CONF.network.endpoint_type,
build_interval=CONF.network.build_interval,
build_timeout=CONF.network.build_timeout,
**manager.default_params)
def create_firewall_rule(self, **kwargs):
body = self.firewall_rules_client.create_firewall_rule(
name=data_utils.rand_name("fw-rule"),
**kwargs)
fw_rule = body['firewall_rule']
self.addCleanup(self._delete_wrapper,
self.firewall_rules_client.delete_firewall_rule,
fw_rule['id'])
return fw_rule
def create_firewall_policy(self, **kwargs):
body = self.firewall_policies_client.create_firewall_policy(
name=data_utils.rand_name("fw-policy"),
**kwargs)
fw_policy = body['firewall_policy']
self.addCleanup(self._delete_wrapper,
self.firewall_policies_client.delete_firewall_policy,
fw_policy['id'])
return fw_policy
def create_firewall(self, **kwargs):
body = self.firewalls_client.create_firewall(
name=data_utils.rand_name("fw"),
**kwargs)
fw = body['firewall']
self.addCleanup(self._delete_wrapper,
self.delete_firewall_and_wait,
fw['id'])
return fw
def delete_firewall_and_wait(self, firewall_id):
self.firewalls_client.delete_firewall(firewall_id)
self._wait_firewall_while(firewall_id, [p_const.PENDING_DELETE],
not_found_ok=True)
def _wait_firewall_ready(self, firewall_id):
self._wait_firewall_while(firewall_id,
[p_const.PENDING_CREATE,
p_const.PENDING_UPDATE])
def _wait_firewall_while(self, firewall_id, statuses, not_found_ok=False):
start = int(time.time())
if not_found_ok:
expected_exceptions = (lib_exc.NotFound)
else:
expected_exceptions = ()
while True:
try:
fw = self.firewalls_client.show_firewall(firewall_id)
except expected_exceptions:
break
status = fw['firewall']['status']
if status not in statuses:
break
if int(time.time()) - start >= self.firewalls_client.build_timeout:
msg = ("Firewall %(firewall)s failed to reach "
"non PENDING status (current %(status)s)") % {
"firewall": firewall_id,
"status": status,
}
raise exceptions.TimeoutException(msg)
time.sleep(1)
neutron-fwaas-8.0.0/neutron_fwaas/tests/tempest_plugin/tests/api/ 0000775 0005670 0005671 00000000000 12701410073 026433 5 ustar jenkins jenkins 0000000 0000000 neutron-fwaas-8.0.0/neutron_fwaas/tests/tempest_plugin/tests/api/test_fwaas_extensions.py 0000664 0005670 0005671 00000040532 12701407720 033435 0 ustar jenkins jenkins 0000000 0000000 # Copyright 2014 NEC Corporation. All rights reserved.
#
# 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.
import six
from tempest import config
from tempest import exceptions
from tempest.lib.common.utils import data_utils
from tempest.lib import exceptions as lib_exc
from tempest import test
from neutron_fwaas.tests.tempest_plugin.tests.api import base
CONF = config.CONF
class FWaaSExtensionTestJSON(base.BaseFWaaSTest):
"""
Tests the following operations in the Neutron API using the REST client for
Neutron:
List firewall rules
Create firewall rule
Update firewall rule
Delete firewall rule
Show firewall rule
List firewall policies
Create firewall policy
Update firewall policy
Insert firewall rule to policy
Remove firewall rule from policy
Insert firewall rule after/before rule in policy
Update firewall policy audited attribute
Delete firewall policy
Show firewall policy
List firewall
Create firewall
Update firewall
Delete firewall
Show firewall
"""
@classmethod
def resource_setup(cls):
super(FWaaSExtensionTestJSON, cls).resource_setup()
if not test.is_extension_enabled('fwaas', 'network'):
msg = "FWaaS Extension not enabled."
raise cls.skipException(msg)
def setUp(self):
super(FWaaSExtensionTestJSON, self).setUp()
self.fw_rule = self.create_firewall_rule(action="allow",
protocol="tcp")
self.fw_policy = self.create_firewall_policy()
def _try_delete_policy(self, policy_id):
# delete policy, if it exists
try:
self.firewall_policies_client.delete_firewall_policy(policy_id)
# if policy is not found, this means it was deleted in the test
except lib_exc.NotFound:
pass
def _try_delete_rule(self, rule_id):
# delete rule, if it exists
try:
self.firewall_rules_client.delete_firewall_rule(rule_id)
# if rule is not found, this means it was deleted in the test
except lib_exc.NotFound:
pass
def _try_delete_firewall(self, fw_id):
# delete firewall, if it exists
try:
self.firewalls_client.delete_firewall(fw_id)
# if firewall is not found, this means it was deleted in the test
except lib_exc.NotFound:
pass
self.firewalls_client.wait_for_resource_deletion(fw_id)
def _wait_until_ready(self, fw_id):
target_states = ('ACTIVE', 'CREATED')
def _wait():
firewall = self.firewalls_client.show_firewall(fw_id)
firewall = firewall['firewall']
return firewall['status'] in target_states
if not test.call_until_true(_wait, CONF.network.build_timeout,
CONF.network.build_interval):
m = ("Timed out waiting for firewall %s to reach %s state(s)" %
(fw_id, target_states))
raise exceptions.TimeoutException(m)
@test.idempotent_id('1b84cf01-9c09-4ce7-bc72-b15e39076468')
def test_list_firewall_rules(self):
# List firewall rules
fw_rules = self.firewall_rules_client.list_firewall_rules()
fw_rules = fw_rules['firewall_rules']
self.assertIn((self.fw_rule['id'],
self.fw_rule['name'],
self.fw_rule['action'],
self.fw_rule['protocol'],
self.fw_rule['ip_version'],
self.fw_rule['enabled']),
[(m['id'],
m['name'],
m['action'],
m['protocol'],
m['ip_version'],
m['enabled']) for m in fw_rules])
@test.idempotent_id('563564f7-7077-4f5e-8cdc-51f37ae5a2b9')
def test_create_update_delete_firewall_rule(self):
# Create firewall rule
body = self.firewall_rules_client.create_firewall_rule(
name=data_utils.rand_name("fw-rule"),
action="allow",
protocol="tcp")
fw_rule_id = body['firewall_rule']['id']
# Update firewall rule
body = self.firewall_rules_client.update_firewall_rule(fw_rule_id,
shared=True)
self.assertTrue(body["firewall_rule"]['shared'])
# Delete firewall rule
self.firewall_rules_client.delete_firewall_rule(fw_rule_id)
# Confirm deletion
fw_rules = self.firewall_rules_client.list_firewall_rules()
self.assertNotIn(fw_rule_id,
[m['id'] for m in fw_rules['firewall_rules']])
@test.idempotent_id('3ff8c08e-26ff-4034-ae48-810ed213a998')
def test_show_firewall_rule(self):
# show a created firewall rule
fw_rule = self.firewall_rules_client.show_firewall_rule(
self.fw_rule['id'])
for key, value in six.iteritems(fw_rule['firewall_rule']):
self.assertEqual(self.fw_rule[key], value)
@test.idempotent_id('1086dd93-a4c0-4bbb-a1bd-6d4bc62c199f')
def test_list_firewall_policies(self):
fw_policies = self.firewall_policies_client.list_firewall_policies()
fw_policies = fw_policies['firewall_policies']
self.assertIn((self.fw_policy['id'],
self.fw_policy['name'],
self.fw_policy['firewall_rules']),
[(m['id'],
m['name'],
m['firewall_rules']) for m in fw_policies])
@test.idempotent_id('bbf37b6c-498c-421e-9c95-45897d3ed775')
def test_create_update_delete_firewall_policy(self):
# Create firewall policy
body = self.firewall_policies_client.create_firewall_policy(
name=data_utils.rand_name("fw-policy"))
fw_policy_id = body['firewall_policy']['id']
self.addCleanup(self._try_delete_policy, fw_policy_id)
# Update firewall policy
body = self.firewall_policies_client.update_firewall_policy(
fw_policy_id,
shared=True,
name="updated_policy")
updated_fw_policy = body["firewall_policy"]
self.assertTrue(updated_fw_policy['shared'])
self.assertEqual("updated_policy", updated_fw_policy['name'])
# Delete firewall policy
self.firewall_policies_client.delete_firewall_policy(fw_policy_id)
# Confirm deletion
fw_policies = self.firewall_policies_client.list_firewall_policies()
fw_policies = fw_policies['firewall_policies']
self.assertNotIn(fw_policy_id, [m['id'] for m in fw_policies])
@test.idempotent_id('1df59b3a-517e-41d4-96f6-fc31cf4ecff2')
def test_show_firewall_policy(self):
# show a created firewall policy
fw_policy = self.firewall_policies_client.show_firewall_policy(
self.fw_policy['id'])
fw_policy = fw_policy['firewall_policy']
for key, value in six.iteritems(fw_policy):
self.assertEqual(self.fw_policy[key], value)
@test.idempotent_id('02082a03-3cdd-4789-986a-1327dd80bfb7')
def test_create_show_delete_firewall(self):
# Create tenant network resources required for an ACTIVE firewall
network = self.create_network()
subnet = self.create_subnet(network)
router = self.create_router(
data_utils.rand_name('router-'),
admin_state_up=True)
self.routers_client.add_router_interface(router['id'],
subnet_id=subnet['id'])
# Create firewall
body = self.firewalls_client.create_firewall(
name=data_utils.rand_name("firewall"),
firewall_policy_id=self.fw_policy['id'])
created_firewall = body['firewall']
firewall_id = created_firewall['id']
self.addCleanup(self._try_delete_firewall, firewall_id)
# Wait for the firewall resource to become ready
self._wait_until_ready(firewall_id)
# show a created firewall
firewall = self.firewalls_client.show_firewall(firewall_id)
firewall = firewall['firewall']
for key, value in six.iteritems(firewall):
if key == 'status':
continue
self.assertEqual(created_firewall[key], value)
# list firewall
firewalls = self.firewalls_client.list_firewalls()
firewalls = firewalls['firewalls']
self.assertIn((created_firewall['id'],
created_firewall['name'],
created_firewall['firewall_policy_id']),
[(m['id'],
m['name'],
m['firewall_policy_id']) for m in firewalls])
# Delete firewall
self.firewalls_client.delete_firewall(firewall_id)
@test.idempotent_id('1355cf5c-77d4-4bb9-87d7-e50c194d08b5')
def test_firewall_insertion_mode_add_remove_router(self):
# Create routers
router1 = self.create_router(
data_utils.rand_name('router-'),
admin_state_up=True)
router2 = self.create_router(
data_utils.rand_name('router-'),
admin_state_up=True)
# Create firewall on a router1
body = self.firewalls_client.create_firewall(
name=data_utils.rand_name("firewall"),
firewall_policy_id=self.fw_policy['id'],
router_ids=[router1['id']])
created_firewall = body['firewall']
firewall_id = created_firewall['id']
self.addCleanup(self._try_delete_firewall, firewall_id)
self.assertEqual([router1['id']], created_firewall['router_ids'])
# Wait for the firewall resource to become ready
self._wait_until_ready(firewall_id)
# Add router2 to the firewall
body = self.firewalls_client.update_firewall(
firewall_id, router_ids=[router1['id'], router2['id']])
updated_firewall = body['firewall']
self.assertIn(router2['id'], updated_firewall['router_ids'])
self.assertEqual(2, len(updated_firewall['router_ids']))
# Wait for the firewall resource to become ready
self._wait_until_ready(firewall_id)
# Remove router1 from the firewall
body = self.firewalls_client.update_firewall(
firewall_id, router_ids=[router2['id']])
updated_firewall = body['firewall']
self.assertNotIn(router1['id'], updated_firewall['router_ids'])
self.assertEqual(1, len(updated_firewall['router_ids']))
@test.idempotent_id('c60ceff5-d51f-451d-b6e6-cb983d16ab6b')
def test_firewall_insertion_mode_one_firewall_per_router(self):
# Create router required for an ACTIVE firewall
router = self.create_router(
data_utils.rand_name('router1-'),
admin_state_up=True)
# Create firewall
body = self.firewalls_client.create_firewall(
name=data_utils.rand_name("firewall"),
firewall_policy_id=self.fw_policy['id'],
router_ids=[router['id']])
created_firewall = body['firewall']
self.addCleanup(self._try_delete_firewall, created_firewall['id'])
# Try to create firewall with the same router
self.assertRaisesRegexp(
lib_exc.Conflict,
"An object with that identifier already exists",
self.firewalls_client.create_firewall,
name=data_utils.rand_name("firewall"),
firewall_policy_id=self.fw_policy['id'],
router_ids=[router['id']])
@test.attr(type='smoke')
@test.idempotent_id('53305b4b-9897-4e01-87c0-2ae386083180')
def test_firewall_rule_insertion_position_removal_rule_from_policy(self):
# Create firewall rule
body = self.firewall_rules_client.create_firewall_rule(
name=data_utils.rand_name("fw-rule"),
action="allow",
protocol="tcp")
fw_rule_id1 = body['firewall_rule']['id']
self.addCleanup(self._try_delete_rule, fw_rule_id1)
# Create firewall policy
body = self.firewall_policies_client.create_firewall_policy(
name=data_utils.rand_name("fw-policy"))
fw_policy_id = body['firewall_policy']['id']
self.addCleanup(self._try_delete_policy, fw_policy_id)
# Insert rule to firewall policy
self.firewall_policies_client.insert_firewall_rule_in_policy(
fw_policy_id, fw_rule_id1, '', '')
# Verify insertion of rule in policy
self.assertIn(fw_rule_id1, self._get_list_fw_rule_ids(fw_policy_id))
# Create another firewall rule
body = self.firewall_rules_client.create_firewall_rule(
name=data_utils.rand_name("fw-rule"),
action="allow",
protocol="icmp")
fw_rule_id2 = body['firewall_rule']['id']
self.addCleanup(self._try_delete_rule, fw_rule_id2)
# Insert rule to firewall policy after the first rule
self.firewall_policies_client.insert_firewall_rule_in_policy(
fw_policy_id, fw_rule_id2, fw_rule_id1, '')
# Verify the position of rule after insertion
fw_rule = self.firewall_rules_client.show_firewall_rule(
fw_rule_id2)
self.assertEqual(int(fw_rule['firewall_rule']['position']), 2)
# Remove rule from the firewall policy
self.firewall_policies_client.remove_firewall_rule_from_policy(
fw_policy_id, fw_rule_id2)
# Insert rule to firewall policy before the first rule
self.firewall_policies_client.insert_firewall_rule_in_policy(
fw_policy_id, fw_rule_id2, '', fw_rule_id1)
# Verify the position of rule after insertion
fw_rule = self.firewall_rules_client.show_firewall_rule(
fw_rule_id2)
self.assertEqual(int(fw_rule['firewall_rule']['position']), 1)
# Remove rule from the firewall policy
self.firewall_policies_client.remove_firewall_rule_from_policy(
fw_policy_id, fw_rule_id2)
# Verify removal of rule from firewall policy
self.assertNotIn(fw_rule_id2, self._get_list_fw_rule_ids(fw_policy_id))
# Remove rule from the firewall policy
self.firewall_policies_client.remove_firewall_rule_from_policy(
fw_policy_id, fw_rule_id1)
# Verify removal of rule from firewall policy
self.assertNotIn(fw_rule_id1, self._get_list_fw_rule_ids(fw_policy_id))
def _get_list_fw_rule_ids(self, fw_policy_id):
fw_policy = self.firewall_policies_client.show_firewall_policy(
fw_policy_id)
return [ruleid for ruleid in fw_policy['firewall_policy']
['firewall_rules']]
@test.idempotent_id('8515ca8a-0d2f-4298-b5ff-6f924e4587ca')
def test_update_firewall_policy_audited_attribute(self):
# Create firewall rule
body = self.firewall_rules_client.create_firewall_rule(
name=data_utils.rand_name("fw-rule"),
action="allow",
protocol="icmp")
fw_rule_id = body['firewall_rule']['id']
self.addCleanup(self._try_delete_rule, fw_rule_id)
# Create firewall policy
body = self.firewall_policies_client.create_firewall_policy(
name=data_utils.rand_name('fw-policy'))
fw_policy_id = body['firewall_policy']['id']
self.addCleanup(self._try_delete_policy, fw_policy_id)
self.assertFalse(body['firewall_policy']['audited'])
# Update firewall policy audited attribute to true
self.firewall_policies_client.update_firewall_policy(fw_policy_id,
audited=True)
# Insert Firewall rule to firewall policy
self.firewall_policies_client.insert_firewall_rule_in_policy(
fw_policy_id, fw_rule_id, '', '')
body = self.firewall_policies_client.show_firewall_policy(
fw_policy_id)
self.assertFalse(body['firewall_policy']['audited'])
neutron-fwaas-8.0.0/neutron_fwaas/tests/tempest_plugin/tests/api/__init__.py 0000664 0005670 0005671 00000000000 12701407720 030537 0 ustar jenkins jenkins 0000000 0000000 neutron-fwaas-8.0.0/neutron_fwaas/tests/tempest_plugin/tests/api/base.py 0000664 0005670 0005671 00000001555 12701407720 027732 0 ustar jenkins jenkins 0000000 0000000 # Copyright (c) 2015 Midokura SARL
# All Rights Reserved.
#
# 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.
from tempest.api.network import base
from neutron_fwaas.tests.tempest_plugin.tests import fwaas_client
class BaseFWaaSTest(fwaas_client.FWaaSClientMixin, base.BaseNetworkTest):
_delete_wrapper = base.BaseNetworkTest._try_delete_resource
neutron-fwaas-8.0.0/neutron_fwaas/tests/tempest_plugin/tests/scenario/ 0000775 0005670 0005671 00000000000 12701410073 027465 5 ustar jenkins jenkins 0000000 0000000 neutron-fwaas-8.0.0/neutron_fwaas/tests/tempest_plugin/tests/scenario/__init__.py 0000664 0005670 0005671 00000000000 12701407720 031571 0 ustar jenkins jenkins 0000000 0000000 neutron-fwaas-8.0.0/neutron_fwaas/tests/tempest_plugin/tests/scenario/base.py 0000664 0005670 0005671 00000005423 12701407720 030762 0 ustar jenkins jenkins 0000000 0000000 # Copyright (c) 2015 Midokura SARL
# All Rights Reserved.
#
# 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.
from tempest import config
from tempest.lib.common import ssh
from tempest.lib import exceptions as lib_exc
from tempest.scenario import manager
from neutron_fwaas.tests.tempest_plugin.tests import fwaas_client
CONF = config.CONF
class FWaaSScenarioTest(fwaas_client.FWaaSClientMixin,
manager.NetworkScenarioTest):
_delete_wrapper = manager.NetworkScenarioTest.delete_wrapper
def check_connectivity(self, ip_address, username=None, private_key=None,
should_connect=True,
check_icmp=True, check_ssh=True,
check_reverse_icmp_ip=None,
should_reverse_connect=True):
if should_connect:
msg = "Timed out waiting for %s to become reachable" % ip_address
else:
msg = "ip address %s is reachable" % ip_address
if check_icmp:
ok = self.ping_ip_address(ip_address,
should_succeed=should_connect)
self.assertTrue(ok, msg=msg)
if check_ssh:
connect_timeout = CONF.validation.connect_timeout
kwargs = {}
if not should_connect:
# Use a shorter timeout for negative case
kwargs['timeout'] = 1
try:
client = ssh.Client(ip_address, username, pkey=private_key,
channel_timeout=connect_timeout,
**kwargs)
client.test_connection_auth()
self.assertTrue(should_connect, "Unexpectedly reachable")
if check_reverse_icmp_ip:
cmd = 'ping -c1 -w1 %s' % check_reverse_icmp_ip
try:
client.exec_command(cmd)
self.assertTrue(should_reverse_connect,
"Unexpectedly reachable (reverse)")
except lib_exc.SSHExecCommandFailed:
if should_reverse_connect:
raise
except lib_exc.SSHTimeout:
if should_connect:
raise
neutron-fwaas-8.0.0/neutron_fwaas/tests/tempest_plugin/tests/scenario/test_fwaas.py 0000664 0005670 0005671 00000037076 12701407720 032221 0 ustar jenkins jenkins 0000000 0000000 # Copyright (c) 2015 Midokura SARL
# All Rights Reserved.
#
# 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.
import testscenarios
from tempest import config
from tempest import test
from neutron_fwaas.tests.tempest_plugin.tests.scenario import base
CONF = config.CONF
load_tests = testscenarios.load_tests_apply_scenarios
class TestFWaaS(base.FWaaSScenarioTest):
scenarios = [
('without router insersion', {
'router_insertion': False,
}),
('with router insersion', {
'router_insertion': True,
}),
]
def setUp(self):
super(TestFWaaS, self).setUp()
required_exts = ['fwaas', 'security-group', 'router']
if self.router_insertion:
required_exts.append('fwaasrouterinsertion')
for ext in required_exts:
if not test.is_extension_enabled(ext, 'network'):
msg = "%s Extension not enabled." % ext
raise self.skipException(msg)
self._router_ids = None
def _create_server(self, network, security_group=None):
keys = self.create_keypair()
kwargs = {}
if security_group is not None:
kwargs['security_groups'] = [{'name': security_group['name']}]
server = self.create_server(
key_name=keys['name'],
networks=[{'uuid': network['id']}],
wait_until='ACTIVE',
**kwargs)
return server, keys
def _create_firewall(self, **kwargs):
if self._router_ids is not None:
kwargs['router_ids'] = self._router_ids
return self.create_firewall(**kwargs)
def _empty_policy(self, **kwargs):
# NOTE(yamamoto): an empty policy would deny all
fw_policy = self.create_firewall_policy(firewall_rules=[])
fw = self._create_firewall(firewall_policy_id=fw_policy['id'])
self._wait_firewall_ready(fw['id'])
return {
'fw': fw,
'fw_policy': fw_policy,
}
def _all_disabled_rules(self, **kwargs):
# NOTE(yamamoto): a policy whose rules are all disabled would deny all
fw_rule = self.create_firewall_rule(action="allow", enabled=False)
fw_policy = self.create_firewall_policy(firewall_rules=[fw_rule['id']])
fw = self._create_firewall(firewall_policy_id=fw_policy['id'])
self._wait_firewall_ready(fw['id'])
return {
'fw': fw,
'fw_policy': fw_policy,
'fw_rule': fw_rule,
}
def _block_ip(self, server1_fixed_ip, server2_fixed_ip, **kwargs):
rules = [
# NOTE(yamamoto): The filtering is taken place after
# destination ip is rewritten to fixed-ip.
self.create_firewall_rule(destination_ip_address=server1_fixed_ip,
action="deny"),
self.create_firewall_rule(destination_ip_address=server2_fixed_ip,
action="deny"),
self.create_firewall_rule(action="allow"),
]
rule_ids = [r['id'] for r in rules]
fw_policy = self.create_firewall_policy(firewall_rules=rule_ids)
fw = self._create_firewall(firewall_policy_id=fw_policy['id'])
self._wait_firewall_ready(fw['id'])
return {
'fw': fw,
'fw_policy': fw_policy,
'server1_fixed_ip': server1_fixed_ip,
'server2_fixed_ip': server2_fixed_ip,
}
def _block_icmp(self, **kwargs):
fw_rule = self.create_firewall_rule(
protocol="icmp",
action="deny")
fw_rule_allow = self.create_firewall_rule(
action="allow")
fw_policy = self.create_firewall_policy(
firewall_rules=[fw_rule['id'], fw_rule_allow['id']])
fw = self._create_firewall(firewall_policy_id=fw_policy['id'])
self._wait_firewall_ready(fw['id'])
return {
'fw': fw,
'fw_policy': fw_policy,
'fw_rule': fw_rule,
}
def _block_all_with_default_allow(self, **kwargs):
fw_rule = self.create_firewall_rule(
action="deny")
fw_rule_allow = self.create_firewall_rule(
action="allow")
fw_policy = self.create_firewall_policy(
firewall_rules=[fw_rule['id'], fw_rule_allow['id']])
fw = self._create_firewall(firewall_policy_id=fw_policy['id'])
self._wait_firewall_ready(fw['id'])
return {
'fw': fw,
'fw_policy': fw_policy,
'fw_rule': fw_rule,
}
def _admin_disable(self, **kwargs):
# NOTE(yamamoto): A firewall with admin_state_up=False would block all
fw_rule = self.create_firewall_rule(action="allow")
fw_policy = self.create_firewall_policy(firewall_rules=[fw_rule['id']])
fw = self._create_firewall(firewall_policy_id=fw_policy['id'],
admin_state_up=False)
self._wait_firewall_ready(fw['id'])
return {
'fw': fw,
'fw_policy': fw_policy,
'fw_rule': fw_rule,
}
def _allow_ssh_and_icmp(self, ctx):
fw_ssh_rule = self.create_firewall_rule(
protocol="tcp",
destination_port=22,
action="allow")
fw_icmp_rule = self.create_firewall_rule(
protocol="icmp",
action="allow")
for rule in [fw_ssh_rule, fw_icmp_rule]:
self.firewall_policies_client.insert_firewall_rule_in_policy(
firewall_policy_id=ctx['fw_policy']['id'],
firewall_rule_id=rule['id'],
insert_before=ctx['fw_rule']['id'])
self.addCleanup(
self._remove_rule_and_wait,
firewall_id=ctx['fw']['id'],
firewall_policy_id=ctx['fw_policy']['id'],
firewall_rule_id=rule['id'])
self._wait_firewall_ready(ctx['fw']['id'])
def _remove_rule_and_wait(self, firewall_id, firewall_policy_id,
firewall_rule_id):
self.firewall_policies_client.remove_firewall_rule_from_policy(
firewall_policy_id=firewall_policy_id,
firewall_rule_id=firewall_rule_id)
self._wait_firewall_ready(firewall_id)
def _delete_fw(self, ctx):
self.delete_firewall_and_wait(ctx['fw']['id'])
def _set_admin_up(self, firewall_id, up):
self.firewalls_client.update_firewall(firewall_id=firewall_id,
admin_state_up=up)
self._wait_firewall_ready(firewall_id=firewall_id)
def _admin_enable(self, ctx):
self._set_admin_up(ctx['fw']['id'], up=True)
def _remove_rule(self, ctx):
self._remove_rule_and_wait(
firewall_id=ctx['fw']['id'],
firewall_policy_id=ctx['fw_policy']['id'],
firewall_rule_id=ctx['fw_rule']['id'])
def _disable_rule(self, ctx):
self.firewall_rules_client.update_firewall_rule(
firewall_rule_id=ctx['fw_rule']['id'],
enabled=False)
self._wait_firewall_ready(ctx['fw']['id'])
def _allow_ip(self, ctx):
self._delete_fw(ctx)
server1_fixed_ip = ctx['server1_fixed_ip']
server2_fixed_ip = ctx['server2_fixed_ip']
rules = [
# NOTE(yamamoto): The filtering is taken place after
# destination ip is rewritten to fixed-ip.
# The return traffic should be allowed regardless
# of firewall rules.
self.create_firewall_rule(
destination_ip_address=server1_fixed_ip,
action="allow"),
self.create_firewall_rule(
destination_ip_address=server2_fixed_ip,
action="allow"),
]
rule_ids = [r['id'] for r in rules]
fw_policy = self.create_firewall_policy(firewall_rules=rule_ids)
fw = self._create_firewall(firewall_policy_id=fw_policy['id'])
self._wait_firewall_ready(fw['id'])
def _confirm_allowed(self, **kwargs):
self.check_connectivity(check_reverse_icmp_ip=self._public_gateway_ip,
**kwargs)
def _confirm_allowed_oneway(self, **kwargs):
# Can ping and ssh, but can't ping back to the public gateway.
# Same as _confirm_allowed if _public_gateway_ip is None.
self.check_connectivity(check_reverse_icmp_ip=self._public_gateway_ip,
should_reverse_connect=False, **kwargs)
def _confirm_blocked(self, **kwargs):
self.check_connectivity(should_connect=False, **kwargs)
def _confirm_icmp_blocked_but_tcp(self, **kwargs):
self.check_connectivity(should_connect=False, check_ssh=False,
**kwargs)
self.check_connectivity(check_icmp=False, **kwargs)
def _create_topology(self):
"""Create a topology for testing
+--------+ +-----------+
|"server"| | "subnet" |
| VM +-------------+ "network" |
+--------+ +----+------+
|
| router interface port
+----+-----+
| "router" |
+----+-----+
| router gateway port
|
|
+----+------------------+
| existing network |
| ("public_network_id") |
+-----------------------+
"""
public_network_id = CONF.network.public_network_id
network, subnet, router = self.create_networks()
security_group = self._create_security_group()
server, keys = self._create_server(network,
security_group=security_group)
private_key = keys['private_key']
server_floating_ip = self.create_floating_ip(server, public_network_id)
fixed_ip = server['addresses'].values()[0][0]['addr']
floating_ip = server_floating_ip.floating_ip_address
return fixed_ip, floating_ip, private_key, router
def _get_public_gateway_ip(self):
self._public_gateway_ip = None
router = self._get_router()
ext_gw_info = router['external_gateway_info']
ext_fixed_ips = ext_gw_info['external_fixed_ips']
for ip in ext_fixed_ips:
subnet_id = ip['subnet_id']
res = self.admin_manager.subnets_client.show_subnet(subnet_id)
subnet = res['subnet']
# REVISIT(yamamoto): IPv4 assumption
if subnet['ip_version'] == 4:
self._public_gateway_ip = subnet['gateway_ip']
return
def _test_firewall_basic(self, block, allow=None,
confirm_allowed=None, confirm_blocked=None):
if allow is None:
allow = self._delete_fw
if confirm_allowed is None:
confirm_allowed = self._confirm_allowed
if confirm_blocked is None:
confirm_blocked = self._confirm_blocked
ssh_login = CONF.validation.image_ssh_user
if self.router_insertion and CONF.network.public_router_id:
# NOTE(yamamoto): If public_router_id is configured
# router1 and router2 will be the same router.
msg = "This test assumes no public_router_id configured"
raise self.skipException(msg)
server1_fixed_ip, server1_floating_ip, private_key1, router1 = \
self._create_topology()
server2_fixed_ip, server2_floating_ip, private_key2, router2 = \
self._create_topology()
self._get_public_gateway_ip()
if self.router_insertion:
# Specify the router when creating a firewall and ensures that
# the other router (router2) is not affected by the firewall
self._router_ids = [router1['id']]
confirm_allowed2 = self.check_connectivity
confirm_blocked2 = self.check_connectivity
else:
# Without router insertion, all routers should be affected
# equally
confirm_allowed2 = confirm_allowed
confirm_blocked2 = confirm_blocked
self.check_connectivity(ip_address=server1_floating_ip,
username=ssh_login,
private_key=private_key1)
self.check_connectivity(ip_address=server2_floating_ip,
username=ssh_login,
private_key=private_key2)
ctx = block(server1_fixed_ip=server1_fixed_ip,
server1_floating_ip=server1_floating_ip,
server2_fixed_ip=server2_fixed_ip,
server2_floating_ip=server2_floating_ip)
confirm_blocked(ip_address=server1_floating_ip, username=ssh_login,
private_key=private_key1)
confirm_blocked2(ip_address=server2_floating_ip, username=ssh_login,
private_key=private_key2)
allow(ctx)
confirm_allowed(ip_address=server1_floating_ip, username=ssh_login,
private_key=private_key1)
confirm_allowed2(ip_address=server2_floating_ip, username=ssh_login,
private_key=private_key2)
@test.idempotent_id('f970f6b3-6541-47ac-a9ea-f769be1e21a8')
def test_firewall_block_ip(self):
self._test_firewall_basic(block=self._block_ip, allow=self._allow_ip,
confirm_allowed=self._confirm_allowed_oneway)
@test.idempotent_id('b985d010-994a-4055-bd5c-9e961464ccde')
def test_firewall_block_icmp(self):
self._test_firewall_basic(
block=self._block_icmp,
confirm_blocked=self._confirm_icmp_blocked_but_tcp)
@test.idempotent_id('ca473af0-26f9-4fad-9550-1c34371c900e')
def test_firewall_insert_rule(self):
self._test_firewall_basic(
block=self._block_icmp,
allow=self._allow_ssh_and_icmp,
confirm_blocked=self._confirm_icmp_blocked_but_tcp)
@test.idempotent_id('54a937a6-cecf-444c-b3f9-b67a1c1b7411')
def test_firewall_remove_rule(self):
self._test_firewall_basic(block=self._block_all_with_default_allow,
allow=self._remove_rule)
@test.idempotent_id('12a18776-9b60-4479-9988-f45971c96a92')
def test_firewall_disable_rule(self):
self._test_firewall_basic(block=self._block_all_with_default_allow,
allow=self._disable_rule)
@test.idempotent_id('a2a58c1f-49ad-4b5f-9463-e746b9efe08a')
def test_firewall_empty_policy(self):
self._test_firewall_basic(block=self._empty_policy)
@test.idempotent_id('477a47e0-5156-4784-9417-f77970d85c36')
def test_firewall_all_disabled_rules(self):
self._test_firewall_basic(block=self._all_disabled_rules)
@test.idempotent_id('a83f51c5-1a18-4d2a-a778-c368e4d95c29')
def test_firewall_admin_disable(self):
self._test_firewall_basic(block=self._admin_disable,
allow=self._admin_enable)
neutron-fwaas-8.0.0/neutron_fwaas/tests/tempest_plugin/__init__.py 0000664 0005670 0005671 00000000000 12701407720 026624 0 ustar jenkins jenkins 0000000 0000000 neutron-fwaas-8.0.0/neutron_fwaas/tests/tempest_plugin/services/ 0000775 0005670 0005671 00000000000 12701410073 026343 5 ustar jenkins jenkins 0000000 0000000 neutron-fwaas-8.0.0/neutron_fwaas/tests/tempest_plugin/services/__init__.py 0000664 0005670 0005671 00000000000 12701407720 030447 0 ustar jenkins jenkins 0000000 0000000 neutron-fwaas-8.0.0/neutron_fwaas/tests/tempest_plugin/services/client.py 0000664 0005670 0005671 00000010647 12701407720 030210 0 ustar jenkins jenkins 0000000 0000000 # Copyright (c) 2015 Midokura SARL
# All Rights Reserved.
#
# 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.
from tempest.lib import exceptions as lib_exc
from tempest.lib.services.network import base
class FirewallsClient(base.BaseNetworkClient):
def create_firewall(self, **kwargs):
uri = '/fw/firewalls'
post_data = {'firewall': kwargs}
return self.create_resource(uri, post_data)
def update_firewall(self, firewall_id, **kwargs):
uri = '/fw/firewalls/%s' % firewall_id
post_data = {'firewall': kwargs}
return self.update_resource(uri, post_data)
def show_firewall(self, firewall_id, **fields):
uri = '/fw/firewalls/%s' % firewall_id
return self.show_resource(uri, **fields)
def delete_firewall(self, firewall_id):
uri = '/fw/firewalls/%s' % firewall_id
return self.delete_resource(uri)
def list_firewalls(self, **filters):
uri = '/fw/firewalls'
return self.list_resources(uri, **filters)
def is_resource_deleted(self, id):
try:
self.show_firewall(id)
except lib_exc.NotFound:
return True
return False
@property
def resource_type(self):
"""Returns the primary type of resource this client works with."""
return 'firewall'
class FirewallRulesClient(base.BaseNetworkClient):
def create_firewall_rule(self, **kwargs):
uri = '/fw/firewall_rules'
post_data = {'firewall_rule': kwargs}
return self.create_resource(uri, post_data)
def update_firewall_rule(self, firewall_rule_id, **kwargs):
uri = '/fw/firewall_rules/%s' % firewall_rule_id
post_data = {'firewall_rule': kwargs}
return self.update_resource(uri, post_data)
def show_firewall_rule(self, firewall_rule_id, **fields):
uri = '/fw/firewall_rules/%s' % firewall_rule_id
return self.show_resource(uri, **fields)
def delete_firewall_rule(self, firewall_rule_id):
uri = '/fw/firewall_rules/%s' % firewall_rule_id
return self.delete_resource(uri)
def list_firewall_rules(self, **filters):
uri = '/fw/firewall_rules'
return self.list_resources(uri, **filters)
class FirewallPoliciesClient(base.BaseNetworkClient):
def create_firewall_policy(self, **kwargs):
uri = '/fw/firewall_policies'
post_data = {'firewall_policy': kwargs}
return self.create_resource(uri, post_data)
def update_firewall_policy(self, firewall_policy_id, **kwargs):
uri = '/fw/firewall_policies/%s' % firewall_policy_id
post_data = {'firewall_policy': kwargs}
return self.update_resource(uri, post_data)
def show_firewall_policy(self, firewall_policy_id, **fields):
uri = '/fw/firewall_policies/%s' % firewall_policy_id
return self.show_resource(uri, **fields)
def delete_firewall_policy(self, firewall_policy_id):
uri = '/fw/firewall_policies/%s' % firewall_policy_id
return self.delete_resource(uri)
def list_firewall_policies(self, **filters):
uri = '/fw/firewall_policies'
return self.list_resources(uri, **filters)
def insert_firewall_rule_in_policy(self, firewall_policy_id,
firewall_rule_id, insert_after='',
insert_before=''):
uri = '/fw/firewall_policies/%s/insert_rule' % firewall_policy_id
data = {
'firewall_rule_id': firewall_rule_id,
'insert_after': insert_after,
'insert_before': insert_before,
}
return self.update_resource(uri, data)
def remove_firewall_rule_from_policy(self, firewall_policy_id,
firewall_rule_id):
uri = '/fw/firewall_policies/%s/remove_rule' % firewall_policy_id
data = {
'firewall_rule_id': firewall_rule_id,
}
return self.update_resource(uri, data)
neutron-fwaas-8.0.0/neutron_fwaas/tests/unit/ 0000775 0005670 0005671 00000000000 12701410073 022440 5 ustar jenkins jenkins 0000000 0000000 neutron-fwaas-8.0.0/neutron_fwaas/tests/unit/__init__.py 0000664 0005670 0005671 00000000000 12701407720 024544 0 ustar jenkins jenkins 0000000 0000000 neutron-fwaas-8.0.0/neutron_fwaas/tests/unit/services/ 0000775 0005670 0005671 00000000000 12701410073 024263 5 ustar jenkins jenkins 0000000 0000000 neutron-fwaas-8.0.0/neutron_fwaas/tests/unit/services/firewall/ 0000775 0005670 0005671 00000000000 12701410073 026070 5 ustar jenkins jenkins 0000000 0000000 neutron-fwaas-8.0.0/neutron_fwaas/tests/unit/services/firewall/__init__.py 0000664 0005670 0005671 00000000000 12701407720 030174 0 ustar jenkins jenkins 0000000 0000000 neutron-fwaas-8.0.0/neutron_fwaas/tests/unit/services/firewall/plugins/ 0000775 0005670 0005671 00000000000 12701410073 027551 5 ustar jenkins jenkins 0000000 0000000 neutron-fwaas-8.0.0/neutron_fwaas/tests/unit/services/firewall/plugins/cisco/ 0000775 0005670 0005671 00000000000 12701410073 030651 5 ustar jenkins jenkins 0000000 0000000 ././@LongLink 0000000 0000000 0000000 00000000150 00000000000 011211 L ustar 0000000 0000000 neutron-fwaas-8.0.0/neutron_fwaas/tests/unit/services/firewall/plugins/cisco/test_cisco_fwaas_plugin.py neutron-fwaas-8.0.0/neutron_fwaas/tests/unit/services/firewall/plugins/cisco/test_cisco_fwaas_plugin0000664 0005670 0005671 00000042606 12701407720 035507 0 ustar jenkins jenkins 0000000 0000000 # Copyright 2015 Cisco Systems, Inc. All rights reserved.
#
# 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.
#
import mock
from neutron.api.v2 import attributes as attr
from neutron import context
from neutron import manager
from neutron.plugins.common import constants as const
from neutron.tests.unit.extensions import test_l3 as test_l3_plugin
import six
import neutron_fwaas
from neutron_fwaas.db.cisco import cisco_fwaas_db as csrfw_db
from neutron_fwaas.extensions.cisco import csr_firewall_insertion
from neutron_fwaas.extensions import firewall
from neutron_fwaas.services.firewall.plugins.cisco import cisco_fwaas_plugin
from neutron_fwaas.tests.unit.db.firewall import (
test_firewall_db as test_db_firewall)
from oslo_config import cfg
# We need the test_l3_plugin to ensure we have a valid port_id corresponding
# to a router interface.
CORE_PLUGIN_KLASS = 'neutron.tests.unit.extensions.test_l3.TestNoL3NatPlugin'
L3_PLUGIN_KLASS = (
'neutron.tests.unit.extensions.test_l3.TestL3NatServicePlugin')
# the plugin under test
CSR_FW_PLUGIN_KLASS = (
"neutron_fwaas.services.firewall.plugins.cisco.cisco_fwaas_plugin."
"CSRFirewallPlugin"
)
extensions_path = neutron_fwaas.extensions.__path__[0] + '/cisco'
class CSR1kvFirewallTestExtensionManager(
test_l3_plugin.L3TestExtensionManager):
def get_resources(self):
res = super(CSR1kvFirewallTestExtensionManager, self).get_resources()
firewall.RESOURCE_ATTRIBUTE_MAP['firewalls'].update(
csr_firewall_insertion.EXTENDED_ATTRIBUTES_2_0['firewalls'])
return res + firewall.Firewall.get_resources()
def get_actions(self):
return []
def get_request_extensions(self):
return []
class CSR1kvFirewallTestCaseBase(test_db_firewall.FirewallPluginDbTestCase,
test_l3_plugin.L3NatTestCaseMixin):
def setUp(self, core_plugin=None, l3_plugin=None, fw_plugin=None,
ext_mgr=None):
self.agentapi_delf_p = mock.patch(test_db_firewall.DELETEFW_PATH,
create=True, new=test_db_firewall.FakeAgentApi().delete_firewall)
self.agentapi_delf_p.start()
cfg.CONF.set_override('api_extensions_path', extensions_path)
# for these tests we need to enable overlapping ips
cfg.CONF.set_default('allow_overlapping_ips', True)
cfg.CONF.set_default('max_routes', 3)
self.saved_attr_map = {}
for resource, attrs in six.iteritems(attr.RESOURCE_ATTRIBUTE_MAP):
self.saved_attr_map[resource] = attrs.copy()
if not core_plugin:
core_plugin = CORE_PLUGIN_KLASS
if l3_plugin is None:
l3_plugin = L3_PLUGIN_KLASS
if not fw_plugin:
fw_plugin = CSR_FW_PLUGIN_KLASS
service_plugins = {'l3_plugin_name': l3_plugin,
'fw_plugin_name': fw_plugin}
if not ext_mgr:
ext_mgr = CSR1kvFirewallTestExtensionManager()
super(test_db_firewall.FirewallPluginDbTestCase, self).setUp(
plugin=core_plugin, service_plugins=service_plugins,
ext_mgr=ext_mgr)
self.core_plugin = manager.NeutronManager.get_plugin()
self.l3_plugin = manager.NeutronManager.get_service_plugins().get(
const.L3_ROUTER_NAT)
self.plugin = manager.NeutronManager.get_service_plugins().get(
const.FIREWALL)
self.callbacks = self.plugin.endpoints[0]
self.setup_notification_driver()
def restore_attribute_map(self):
# Remove the csrfirewallinsertion extension
firewall.RESOURCE_ATTRIBUTE_MAP['firewalls'].pop('port_id')
firewall.RESOURCE_ATTRIBUTE_MAP['firewalls'].pop('direction')
# Restore the original RESOURCE_ATTRIBUTE_MAP
attr.RESOURCE_ATTRIBUTE_MAP = self.saved_attr_map
def tearDown(self):
self.restore_attribute_map()
super(CSR1kvFirewallTestCaseBase, self).tearDown()
def _create_firewall(self, fmt, name, description, firewall_policy_id=None,
admin_state_up=True, expected_res_status=None,
**kwargs):
tenant_id = kwargs.get('tenant_id', self._tenant_id)
port_id = kwargs.get('port_id')
direction = kwargs.get('direction')
if firewall_policy_id is None:
res = self._create_firewall_policy(fmt, 'fwp',
description="firewall_policy",
shared=True,
firewall_rules=[],
audited=True)
firewall_policy = self.deserialize(fmt or self.fmt, res)
firewall_policy_id = firewall_policy["firewall_policy"]["id"]
data = {'firewall': {'name': name,
'description': description,
'firewall_policy_id': firewall_policy_id,
'admin_state_up': admin_state_up,
'tenant_id': tenant_id}}
if port_id:
data['firewall']['port_id'] = port_id
if direction:
data['firewall']['direction'] = direction
firewall_req = self.new_create_request('firewalls', data, fmt)
firewall_res = firewall_req.get_response(self.ext_api)
if expected_res_status:
self.assertEqual(expected_res_status, firewall_res.status_int)
return firewall_res
class TestCiscoFirewallCallbacks(test_db_firewall.FirewallPluginDbTestCase):
def setUp(self):
super(TestCiscoFirewallCallbacks, self).setUp()
self.plugin = cisco_fwaas_plugin.CSRFirewallPlugin()
self.callbacks = self.plugin.endpoints[0]
def test_firewall_deleted(self):
ctx = context.get_admin_context()
with self.firewall_policy(do_delete=False) as fwp:
fwp_id = fwp['firewall_policy']['id']
with self.firewall(firewall_policy_id=fwp_id,
admin_state_up=test_db_firewall.ADMIN_STATE_UP,
do_delete=False) as fw:
fw_id = fw['firewall']['id']
with ctx.session.begin(subtransactions=True):
fw_db = self.plugin._get_firewall(ctx, fw_id)
fw_db['status'] = const.PENDING_DELETE
ctx.session.flush()
res = self.callbacks.firewall_deleted(ctx, fw_id,
host='dummy')
self.assertTrue(res)
self.assertRaises(firewall.FirewallNotFound,
self.plugin.get_firewall,
ctx, fw_id)
class TestCiscoFirewallPlugin(CSR1kvFirewallTestCaseBase,
csrfw_db.CiscoFirewall_db_mixin):
def setUp(self):
super(TestCiscoFirewallPlugin, self).setUp()
self.fake_vendor_ext = {
'host_mngt_ip': '1.2.3.4',
'host_usr_nm': 'admin',
'host_usr_pw': 'cisco',
'if_list': {'port': {'id': 0, 'hosting_info': 'csr'},
'direction': 'default'}
}
self.mock_get_hosting_info = mock.patch.object(
self.plugin, '_get_hosting_info').start()
def test_create_csr_firewall(self):
with self.router(tenant_id=self._tenant_id) as r,\
self.subnet() as s:
body = self._router_interface_action(
'add',
r['router']['id'],
s['subnet']['id'],
None)
port_id = body['port_id']
self.fake_vendor_ext['if_list']['port']['id'] = port_id
self.fake_vendor_ext['if_list']['direction'] = 'inside'
self.mock_get_hosting_info.return_value = self.fake_vendor_ext
with self.firewall(port_id=body['port_id'],
direction='inside') as fw:
ctx = context.get_admin_context()
fw_id = fw['firewall']['id']
csrfw = self.lookup_firewall_csr_association(
ctx, fw_id)
# cant be in PENDING_XXX state for delete clean up
with ctx.session.begin(subtransactions=True):
fw_db = self.plugin._get_firewall(ctx, fw_id)
fw_db['status'] = const.ACTIVE
ctx.session.flush()
self._router_interface_action(
'remove',
r['router']['id'],
s['subnet']['id'],
None)
self.assertEqual('firewall_1', fw['firewall']['name'])
self.assertEqual(port_id, csrfw['port_id'])
self.assertEqual('inside', csrfw['direction'])
def test_create_csr_firewall_only_port_id_specified(self):
with self.router(tenant_id=self._tenant_id) as r, \
self.subnet() as s:
body = self._router_interface_action(
'add',
r['router']['id'],
s['subnet']['id'],
None)
port_id = body['port_id']
self.fake_vendor_ext['if_list']['port']['id'] = port_id
self.fake_vendor_ext['if_list']['direction'] = None
self.mock_get_hosting_info.return_value = self.fake_vendor_ext
with self.firewall(port_id=body['port_id']) as fw:
ctx = context.get_admin_context()
fw_id = fw['firewall']['id']
csrfw = self.lookup_firewall_csr_association(
ctx, fw_id)
# cant be in PENDING_XXX state for delete clean up
with ctx.session.begin(subtransactions=True):
fw_db = self.plugin._get_firewall(ctx, fw_id)
fw_db['status'] = const.ACTIVE
ctx.session.flush()
self._router_interface_action(
'remove',
r['router']['id'],
s['subnet']['id'],
None)
self.assertEqual('firewall_1', fw['firewall']['name'])
self.assertEqual(port_id, csrfw['port_id'])
self.assertIsNone(csrfw['direction'])
def test_create_csr_firewall_no_port_id_no_direction_specified(self):
with self.firewall() as fw:
ctx = context.get_admin_context()
fw_id = fw['firewall']['id']
csrfw = self.lookup_firewall_csr_association(
ctx, fw_id)
# cant be in PENDING_XXX state for delete clean up
with ctx.session.begin(subtransactions=True):
fw_db = self.plugin._get_firewall(ctx, fw_id)
fw_db['status'] = const.ACTIVE
ctx.session.flush()
self.assertEqual('firewall_1', fw['firewall']['name'])
self.assertIsNone(csrfw)
def test_update_csr_firewall(self):
with self.router(tenant_id=self._tenant_id) as r, \
self.subnet() as s:
body = self._router_interface_action(
'add',
r['router']['id'],
s['subnet']['id'],
None)
port_id = body['port_id']
self.fake_vendor_ext['if_list']['port']['id'] = port_id
self.fake_vendor_ext['if_list']['direction'] = 'inside'
self.mock_get_hosting_info.return_value = self.fake_vendor_ext
with self.firewall(port_id=body['port_id'],
direction='both') as fw:
ctx = context.get_admin_context()
fw_id = fw['firewall']['id']
csrfw = self.lookup_firewall_csr_association(
ctx, fw_id)
status_data = {'acl_id': 100}
res = self.callbacks.set_firewall_status(ctx, fw_id,
const.ACTIVE, status_data)
# update direction on same port
data = {'firewall': {'name': 'firewall_2',
'direction': 'both', 'port_id': port_id}}
req = self.new_update_request('firewalls', data,
fw['firewall']['id'])
req.environ['neutron.context'] = context.Context(
'', 'test-tenant')
res = self.deserialize(self.fmt,
req.get_response(self.ext_api))
csrfw = self.lookup_firewall_csr_association(ctx,
fw['firewall']['id'])
self.assertEqual('firewall_2', res['firewall']['name'])
self.assertEqual(port_id, csrfw['port_id'])
self.assertEqual('both', csrfw['direction'])
# cant be in PENDING_XXX state for delete clean up
with ctx.session.begin(subtransactions=True):
fw_db = self.plugin._get_firewall(ctx, fw_id)
fw_db['status'] = const.ACTIVE
ctx.session.flush()
self._router_interface_action(
'remove',
r['router']['id'],
s['subnet']['id'],
None)
def test_update_csr_firewall_port_id(self):
with self.router(tenant_id=self._tenant_id) as r, \
self.subnet() as s1, \
self.subnet(cidr='20.0.0.0/24') as s2:
body = self._router_interface_action(
'add',
r['router']['id'],
s1['subnet']['id'],
None)
port_id1 = body['port_id']
body = self._router_interface_action(
'add',
r['router']['id'],
s2['subnet']['id'],
None)
port_id2 = body['port_id']
self.fake_vendor_ext['if_list']['port']['id'] = port_id1
self.fake_vendor_ext['if_list']['direction'] = 'inside'
self.mock_get_hosting_info.return_value = self.fake_vendor_ext
with self.firewall(port_id=port_id1,
direction='both') as fw:
ctx = context.get_admin_context()
fw_id = fw['firewall']['id']
status_data = {'acl_id': 100}
res = self.callbacks.set_firewall_status(ctx, fw_id,
const.ACTIVE, status_data)
# update direction on same port
data = {'firewall': {'name': 'firewall_2',
'direction': 'both', 'port_id': port_id2}}
req = self.new_update_request('firewalls', data,
fw['firewall']['id'])
req.environ['neutron.context'] = context.Context(
'', 'test-tenant')
res = self.deserialize(self.fmt,
req.get_response(self.ext_api))
csrfw = self.lookup_firewall_csr_association(ctx,
fw['firewall']['id'])
self.assertEqual('firewall_2', res['firewall']['name'])
self.assertEqual(port_id2, csrfw['port_id'])
self.assertEqual('both', csrfw['direction'])
# cant be in PENDING_XXX state for delete clean up
with ctx.session.begin(subtransactions=True):
fw_db = self.plugin._get_firewall(ctx, fw_id)
fw_db['status'] = const.ACTIVE
ctx.session.flush()
self._router_interface_action('remove',
r['router']['id'],
s1['subnet']['id'],
None)
self._router_interface_action(
'remove',
r['router']['id'],
s2['subnet']['id'],
None)
def test_delete_csr_firewall(self):
with self.router(tenant_id=self._tenant_id) as r, \
self.subnet() as s:
body = self._router_interface_action(
'add',
r['router']['id'],
s['subnet']['id'],
None)
port_id = body['port_id']
self.fake_vendor_ext['if_list']['port']['id'] = port_id
self.fake_vendor_ext['if_list']['direction'] = 'inside'
self.mock_get_hosting_info.return_value = self.fake_vendor_ext
with self.firewall(port_id=port_id,
direction='inside', do_delete=False) as fw:
fw_id = fw['firewall']['id']
ctx = context.get_admin_context()
csrfw = self.lookup_firewall_csr_association(ctx,
fw_id)
self.assertIsNotNone(csrfw)
req = self.new_delete_request('firewalls', fw_id)
req.get_response(self.ext_api)
with ctx.session.begin(subtransactions=True):
fw_db = self.plugin._get_firewall(ctx, fw_id)
fw_db['status'] = const.PENDING_DELETE
ctx.session.flush()
self.callbacks.firewall_deleted(ctx, fw_id)
csrfw = self.lookup_firewall_csr_association(ctx,
fw_id)
self.assertIsNone(csrfw)
self._router_interface_action(
'remove',
r['router']['id'],
s['subnet']['id'],
None)
neutron-fwaas-8.0.0/neutron_fwaas/tests/unit/services/firewall/plugins/cisco/__init__.py 0000664 0005670 0005671 00000000000 12701407720 032755 0 ustar jenkins jenkins 0000000 0000000 neutron-fwaas-8.0.0/neutron_fwaas/tests/unit/services/firewall/plugins/__init__.py 0000664 0005670 0005671 00000000000 12701407720 031655 0 ustar jenkins jenkins 0000000 0000000 neutron-fwaas-8.0.0/neutron_fwaas/tests/unit/services/firewall/drivers/ 0000775 0005670 0005671 00000000000 12701410073 027546 5 ustar jenkins jenkins 0000000 0000000 neutron-fwaas-8.0.0/neutron_fwaas/tests/unit/services/firewall/drivers/linux/ 0000775 0005670 0005671 00000000000 12701410073 030705 5 ustar jenkins jenkins 0000000 0000000 neutron-fwaas-8.0.0/neutron_fwaas/tests/unit/services/firewall/drivers/linux/test_iptables_fwaas.py 0000664 0005670 0005671 00000030661 12701407720 035315 0 ustar jenkins jenkins 0000000 0000000 # Copyright 2013 Dell Inc.
# All Rights Reserved.
#
# 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.
import mock
from oslo_config import cfg
from neutron.agent.common import config as a_cfg
from neutron.tests import base
from neutron.tests.unit.api.v2 import test_base as test_api_v2
import neutron_fwaas.services.firewall.drivers.linux.iptables_fwaas as fwaas
_uuid = test_api_v2._uuid
FAKE_SRC_PREFIX = '10.0.0.0/24'
FAKE_DST_PREFIX = '20.0.0.0/24'
FAKE_PROTOCOL = 'tcp'
FAKE_SRC_PORT = 5000
FAKE_DST_PORT = 22
FAKE_FW_ID = 'fake-fw-uuid'
class IptablesFwaasTestCase(base.BaseTestCase):
def setUp(self):
super(IptablesFwaasTestCase, self).setUp()
cfg.CONF.register_opts(a_cfg.ROOT_HELPER_OPTS, 'AGENT')
self.utils_exec_p = mock.patch(
'neutron.agent.linux.utils.execute')
self.utils_exec = self.utils_exec_p.start()
self.iptables_cls_p = mock.patch(
'neutron.agent.linux.iptables_manager.IptablesManager')
self.iptables_cls_p.start()
self.firewall = fwaas.IptablesFwaasDriver()
def _fake_rules_v4(self, fwid, apply_list):
rule_list = []
rule1 = {'enabled': True,
'action': 'allow',
'ip_version': 4,
'protocol': 'tcp',
'destination_port': '80',
'source_ip_address': '10.24.4.2'}
rule2 = {'enabled': True,
'action': 'deny',
'ip_version': 4,
'protocol': 'tcp',
'destination_port': '22'}
rule3 = {'enabled': True,
'action': 'reject',
'ip_version': 4,
'protocol': 'tcp',
'destination_port': '23'}
ingress_chain = ('iv4%s' % fwid)[:11]
egress_chain = ('ov4%s' % fwid)[:11]
for router_info_inst in apply_list:
v4filter_inst = router_info_inst.iptables_manager.ipv4['filter']
v4filter_inst.chains.append(ingress_chain)
v4filter_inst.chains.append(egress_chain)
rule_list.append(rule1)
rule_list.append(rule2)
rule_list.append(rule3)
return rule_list
def _fake_firewall_no_rule(self):
rule_list = []
fw_inst = {'id': FAKE_FW_ID,
'admin_state_up': True,
'tenant_id': 'tenant-uuid',
'firewall_rule_list': rule_list}
return fw_inst
def _fake_firewall(self, rule_list):
fw_inst = {'id': FAKE_FW_ID,
'admin_state_up': True,
'tenant_id': 'tenant-uuid',
'firewall_rule_list': rule_list}
return fw_inst
def _fake_firewall_with_admin_down(self, rule_list):
fw_inst = {'id': FAKE_FW_ID,
'admin_state_up': False,
'tenant_id': 'tenant-uuid',
'firewall_rule_list': rule_list}
return fw_inst
def _fake_apply_list(self, router_count=1, distributed=False,
distributed_mode=None):
apply_list = []
while router_count > 0:
iptables_inst = mock.Mock()
if distributed is not None:
router_inst = {'distributed': distributed}
else:
router_inst = {}
v4filter_inst = mock.Mock()
v6filter_inst = mock.Mock()
v4filter_inst.chains = []
v6filter_inst.chains = []
iptables_inst.ipv4 = {'filter': v4filter_inst}
iptables_inst.ipv6 = {'filter': v6filter_inst}
router_info_inst = mock.Mock()
router_info_inst.iptables_manager = iptables_inst
router_info_inst.snat_iptables_manager = iptables_inst
if distributed_mode == 'dvr':
router_info_inst.dist_fip_count = 1
router_info_inst.router = router_inst
apply_list.append(router_info_inst)
router_count -= 1
return apply_list
def _setup_firewall_with_rules(self, func, router_count=1,
distributed=False, distributed_mode=None):
apply_list = self._fake_apply_list(router_count=router_count,
distributed=distributed, distributed_mode=distributed_mode)
rule_list = self._fake_rules_v4(FAKE_FW_ID, apply_list)
firewall = self._fake_firewall(rule_list)
if distributed:
if distributed_mode == 'dvr_snat':
if_prefix = 'sg-+'
if distributed_mode == 'dvr':
if_prefix = 'rfp-+'
else:
if_prefix = 'qr-+'
distributed_mode = 'legacy'
func(distributed_mode, apply_list, firewall)
invalid_rule = '-m state --state INVALID -j DROP'
est_rule = '-m state --state ESTABLISHED,RELATED -j ACCEPT'
rule1 = '-p tcp --dport 80 -s 10.24.4.2 -j ACCEPT'
rule2 = '-p tcp --dport 22 -j DROP'
rule3 = '-p tcp --dport 23 -j REJECT'
ingress_chain = 'iv4%s' % firewall['id']
egress_chain = 'ov4%s' % firewall['id']
bname = fwaas.iptables_manager.binary_name
ipt_mgr_ichain = '%s-%s' % (bname, ingress_chain[:11])
ipt_mgr_echain = '%s-%s' % (bname, egress_chain[:11])
for router_info_inst in apply_list:
v4filter_inst = router_info_inst.iptables_manager.ipv4['filter']
calls = [mock.call.remove_chain('iv4fake-fw-uuid'),
mock.call.remove_chain('ov4fake-fw-uuid'),
mock.call.remove_chain('fwaas-default-policy'),
mock.call.add_chain('fwaas-default-policy'),
mock.call.add_rule('fwaas-default-policy', '-j DROP'),
mock.call.add_chain(ingress_chain),
mock.call.add_rule(ingress_chain, invalid_rule),
mock.call.add_rule(ingress_chain, est_rule),
mock.call.add_chain(egress_chain),
mock.call.add_rule(egress_chain, invalid_rule),
mock.call.add_rule(egress_chain, est_rule),
mock.call.add_rule(ingress_chain, rule1),
mock.call.add_rule(egress_chain, rule1),
mock.call.add_rule(ingress_chain, rule2),
mock.call.add_rule(egress_chain, rule2),
mock.call.add_rule(ingress_chain, rule3),
mock.call.add_rule(egress_chain, rule3),
mock.call.add_rule('FORWARD',
'-o %s -j %s' % (if_prefix,
ipt_mgr_ichain)),
mock.call.add_rule('FORWARD',
'-i %s -j %s' % (if_prefix,
ipt_mgr_echain)),
mock.call.add_rule('FORWARD',
'-o %s -j %s-fwaas-defau' % (if_prefix,
bname)),
mock.call.add_rule('FORWARD',
'-i %s -j %s-fwaas-defau' % (if_prefix,
bname))]
v4filter_inst.assert_has_calls(calls)
def test_create_firewall_no_rules(self):
apply_list = self._fake_apply_list()
firewall = self._fake_firewall_no_rule()
self.firewall.create_firewall('legacy', apply_list, firewall)
invalid_rule = '-m state --state INVALID -j DROP'
est_rule = '-m state --state ESTABLISHED,RELATED -j ACCEPT'
bname = fwaas.iptables_manager.binary_name
for ip_version in (4, 6):
ingress_chain = ('iv%s%s' % (ip_version, firewall['id']))
egress_chain = ('ov%s%s' % (ip_version, firewall['id']))
calls = [mock.call.remove_chain(
'iv%sfake-fw-uuid' % ip_version),
mock.call.remove_chain(
'ov%sfake-fw-uuid' % ip_version),
mock.call.remove_chain('fwaas-default-policy'),
mock.call.add_chain('fwaas-default-policy'),
mock.call.add_rule('fwaas-default-policy', '-j DROP'),
mock.call.add_chain(ingress_chain),
mock.call.add_rule(ingress_chain, invalid_rule),
mock.call.add_rule(ingress_chain, est_rule),
mock.call.add_chain(egress_chain),
mock.call.add_rule(egress_chain, invalid_rule),
mock.call.add_rule(egress_chain, est_rule),
mock.call.add_rule('FORWARD',
'-o qr-+ -j %s-fwaas-defau' % bname),
mock.call.add_rule('FORWARD',
'-i qr-+ -j %s-fwaas-defau' % bname)]
if ip_version == 4:
v4filter_inst = apply_list[0].iptables_manager.ipv4['filter']
v4filter_inst.assert_has_calls(calls)
else:
v6filter_inst = apply_list[0].iptables_manager.ipv6['filter']
v6filter_inst.assert_has_calls(calls)
def test_create_firewall_with_rules(self):
self._setup_firewall_with_rules(self.firewall.create_firewall)
def test_create_firewall_with_rules_without_distributed_attr(self):
self._setup_firewall_with_rules(self.firewall.create_firewall,
distributed=None)
def test_create_firewall_with_rules_two_routers(self):
self._setup_firewall_with_rules(self.firewall.create_firewall,
router_count=2)
def test_update_firewall_with_rules(self):
self._setup_firewall_with_rules(self.firewall.update_firewall)
def test_update_firewall_with_rules_without_distributed_attr(self):
self._setup_firewall_with_rules(self.firewall.update_firewall,
distributed=None)
def _test_delete_firewall(self, distributed=False):
apply_list = self._fake_apply_list(distributed=distributed)
firewall = self._fake_firewall_no_rule()
self.firewall.delete_firewall('legacy', apply_list, firewall)
ingress_chain = 'iv4%s' % firewall['id']
egress_chain = 'ov4%s' % firewall['id']
calls = [mock.call.remove_chain(ingress_chain),
mock.call.remove_chain(egress_chain),
mock.call.remove_chain('fwaas-default-policy')]
apply_list[0].iptables_manager.ipv4['filter'].assert_has_calls(calls)
def test_delete_firewall(self):
self._test_delete_firewall()
def test_delete_firewall_without_distributed_attr(self):
self._test_delete_firewall(distributed=None)
def test_create_firewall_with_admin_down(self):
apply_list = self._fake_apply_list()
rule_list = self._fake_rules_v4(FAKE_FW_ID, apply_list)
firewall = self._fake_firewall_with_admin_down(rule_list)
self.firewall.create_firewall('legacy', apply_list, firewall)
calls = [mock.call.remove_chain('iv4fake-fw-uuid'),
mock.call.remove_chain('ov4fake-fw-uuid'),
mock.call.remove_chain('fwaas-default-policy'),
mock.call.add_chain('fwaas-default-policy'),
mock.call.add_rule('fwaas-default-policy', '-j DROP')]
apply_list[0].iptables_manager.ipv4['filter'].assert_has_calls(calls)
def test_create_firewall_with_rules_dvr_snat(self):
self._setup_firewall_with_rules(self.firewall.create_firewall,
distributed=True, distributed_mode='dvr_snat')
def test_update_firewall_with_rules_dvr_snat(self):
self._setup_firewall_with_rules(self.firewall.update_firewall,
distributed=True, distributed_mode='dvr_snat')
def test_create_firewall_with_rules_dvr(self):
self._setup_firewall_with_rules(self.firewall.create_firewall,
distributed=True, distributed_mode='dvr')
def test_update_firewall_with_rules_dvr(self):
self._setup_firewall_with_rules(self.firewall.update_firewall,
distributed=True, distributed_mode='dvr')
neutron-fwaas-8.0.0/neutron_fwaas/tests/unit/services/firewall/drivers/linux/__init__.py 0000664 0005670 0005671 00000000000 12701407720 033011 0 ustar jenkins jenkins 0000000 0000000 neutron-fwaas-8.0.0/neutron_fwaas/tests/unit/services/firewall/drivers/mcafee/ 0000775 0005670 0005671 00000000000 12701410073 030766 5 ustar jenkins jenkins 0000000 0000000 neutron-fwaas-8.0.0/neutron_fwaas/tests/unit/services/firewall/drivers/mcafee/__init__.py 0000664 0005670 0005671 00000000000 12701407720 033072 0 ustar jenkins jenkins 0000000 0000000 neutron-fwaas-8.0.0/neutron_fwaas/tests/unit/services/firewall/drivers/mcafee/test_ngfw_fwaas.py 0000664 0005670 0005671 00000021353 12701407720 034532 0 ustar jenkins jenkins 0000000 0000000 # Copyright 2015 Intel Corporation.
# All Rights Reserved.
#
# 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.
import mock
import neutron_fwaas.services.firewall.drivers.mcafee as mcafee
import neutron_fwaas.services.firewall.drivers.mcafee.ngfw_fwaas as fwaas
from neutron.tests import base
FAKE_FIREWALL_ID = 'firewall_id'
FAKE_POLICY_ID = 'policy_id'
FAKE_TENANT_ID = 'tenant_id'
FAKE_ROUTER_ID = 'router_id'
FAKE_FW_NAME = 'fw_name'
class NGFWFwaasTestCase(base.BaseTestCase):
def setUp(self):
super(NGFWFwaasTestCase, self).setUp()
self.firewall = fwaas.NgfwFwaasDriver()
self.rule_list = self._fake_ipv4_rules()
self.apply_list = self._fake_apply_list()
self.post_return = mock.MagicMock()
self.tmp_ref = 'temp_ref'
self.post_return.headers = {'location': self.tmp_ref}
# we generate the policy name by formatting the ids of firewall,
# policy, router
self.policy_name = "%s_%s_%s" % (
FAKE_FIREWALL_ID[0:7], FAKE_POLICY_ID[0:7],
FAKE_ROUTER_ID[0:7])
def _fake_ipv4_rules(self):
rule1 = {'action': 'deny',
'description': '',
'destination_ip_address': None,
'destination_port': '23',
'enabled': True,
'firewall_policy_id': FAKE_POLICY_ID,
'id': '1',
'ip_version': 4,
'name': 'a2',
'position': 1,
'protocol': 'udp',
'shared': False,
'source_ip_address': None,
'source_port': '23',
'tenant_id': FAKE_TENANT_ID}
rule2 = {'action': 'deny',
'description': '',
'destination_ip_address': None,
'destination_port': None,
'enabled': True,
'firewall_policy_id': FAKE_POLICY_ID,
'id': '2',
'ip_version': 4,
'name': 'a3',
'position': 2,
'protocol': 'icmp',
'shared': False,
'source_ip_address': '192.168.100.0/24',
'source_port': None,
'tenant_id': FAKE_TENANT_ID}
rule3 = {'action': 'allow',
'description': '',
'destination_ip_address': None,
'destination_port': None,
'enabled': True,
'firewall_policy_id': FAKE_POLICY_ID,
'id': '3',
'ip_version': 4,
'name': 'a4',
'position': 3,
'protocol': 'tcp',
'shared': False,
'source_ip_address': None,
'source_port': None,
'tenant_id': FAKE_TENANT_ID}
return [rule1, rule2, rule3]
def _fake_firewall(self, rule_list):
fw = {
'admin_state_up': True,
'description': '',
'firewall_policy_id': FAKE_POLICY_ID,
'id': FAKE_FIREWALL_ID,
'name': FAKE_FW_NAME,
'shared': None,
'status': 'PENDING_CREATE',
'tenant_id': FAKE_TENANT_ID,
'firewall_rule_list': rule_list}
return fw
def _fake_apply_list(self):
apply_list = []
router_info_inst = mock.Mock()
fake_interface = mock.Mock()
router_inst = (
{'_interfaces': fake_interface,
'admin_state_up': True,
'distributed': False,
'external_gateway_info': None,
'gw_port_id': None,
'ha': False,
'ha_vr_id': 0,
'id': FAKE_ROUTER_ID,
'name': 'rrr1',
'routes': [],
'status': 'ACTIVE',
'tenant_id': FAKE_TENANT_ID})
router_info_inst.router = router_inst
apply_list.append(router_info_inst)
return apply_list
def test_update_firewall(self):
firewall = self._fake_firewall(self.rule_list)
ref_v4rule = self.tmp_ref + "/fw_ipv4_access_rule"
ref_upload = self.tmp_ref + "/upload"
# NOTE(cbrandily): we replace jsonutils.dumps by identity in order
# to compare dictionaries instead of their json dumps and avoid to
# assume how jsonutils.dumps order dictionaries.
with mock.patch('oslo_serialization.jsonutils.dumps',
side_effect=lambda x: x), \
mock.patch.object(mcafee.smc_api.SMCAPIConnection, 'login'), \
mock.patch.object(mcafee.smc_api.SMCAPIConnection, 'get'), \
mock.patch.object(mcafee.smc_api.SMCAPIConnection, 'logout'), \
mock.patch.object(mcafee.smc_api.SMCAPIConnection, 'post',
return_value=self.post_return) as post:
expected = [
mock.call(
'elements/fw_policy',
{"name": self.policy_name, "template": None}),
mock.call(
'elements/udp_service',
{"min_dst_port": 23, "max_dst_port": 23,
"name": "service-a2", "max_src_port": 23,
"min_src_port": 23}),
mock.call(
ref_v4rule,
{"action": {"action": "discard",
"connection_tracking_options": {}},
"services": {"service": [self.tmp_ref]},
"sources": {"src": ["None"]},
"name": "a2",
"destinations": {"dst": ["None"]}},
raw=True),
mock.call(
'elements/network',
{"ipv4_network": "192.168.100.0/24",
"name": "network-192.168.100.0/24"}),
mock.call(
'elements/icmp_service',
{"icmp_code": 0, "icmp_type": 0, "name": "service22"}),
mock.call(
ref_v4rule,
{"action": {"action": "discard",
"connection_tracking_options": {}},
"services": {"service": [self.tmp_ref]},
"sources": {"src": [self.tmp_ref]},
"name": "a3",
"destinations": {"dst": ["None"]}},
raw=True),
mock.call(
'elements/tcp_service',
{"min_dst_port": 0, "max_dst_port": 65535,
"name": "service-a4", "max_src_port": 65535,
"min_src_port": 0}),
mock.call(
ref_v4rule,
{"action": {"action": "allow",
"connection_tracking_options": {}},
"services": {"service": [self.tmp_ref]},
"sources": {"src": ["None"]},
"name": "a4",
"destinations": {"dst": ["None"]}},
raw=True),
mock.call(ref_upload, '', raw=True)]
self.firewall.update_firewall('legacy', self.apply_list, firewall)
self.assertEqual(expected, post.call_args_list)
def test_create_firewall(self):
self.test_update_firewall()
def test_delete_firewall(self):
firewall = self._fake_firewall(self.rule_list)
get_value = [{'result': [{'name': self.policy_name,
'href': self.tmp_ref}, ]}, ]
with mock.patch.object(mcafee.smc_api.SMCAPIConnection, 'login'), \
mock.patch.object(mcafee.smc_api.SMCAPIConnection, 'get',
return_value=get_value),\
mock.patch.object(mcafee.smc_api.SMCAPIConnection, 'logout'), \
mock.patch.object(mcafee.smc_api.SMCAPIConnection, 'post',
return_value=self.post_return), \
mock.patch.object(mcafee.smc_api.SMCAPIConnection, 'delete'
) as delete:
self.firewall.delete_firewall('legacy', self.apply_list, firewall)
expected = [
mock.call(self.tmp_ref, raw=True),
mock.call(self.tmp_ref, raw=True)
]
self.assertEqual(expected, delete.call_args_list)
neutron-fwaas-8.0.0/neutron_fwaas/tests/unit/services/firewall/drivers/varmour/ 0000775 0005670 0005671 00000000000 12701410073 031241 5 ustar jenkins jenkins 0000000 0000000 neutron-fwaas-8.0.0/neutron_fwaas/tests/unit/services/firewall/drivers/varmour/__init__.py 0000664 0005670 0005671 00000000000 12701407720 033345 0 ustar jenkins jenkins 0000000 0000000 neutron-fwaas-8.0.0/neutron_fwaas/tests/unit/services/firewall/drivers/varmour/test_varmour_fwaas.py0000664 0005670 0005671 00000021317 12701407720 035537 0 ustar jenkins jenkins 0000000 0000000 # Copyright 2013 vArmour Networks Inc.
# All Rights Reserved.
#
# 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.
import mock
from neutron.agent.common import config as agent_config
from neutron.agent.l3 import config as l3_config
from neutron.agent.l3 import ha
from neutron.agent.l3 import router_info
from neutron.agent.linux import interface
from neutron.common import config as base_config
from neutron.tests import base
from neutron_lib import constants as l3_constants
from oslo_utils import uuidutils
from neutron_fwaas.services.firewall.agents.varmour import varmour_router
from neutron_fwaas.services.firewall.drivers.varmour import varmour_fwaas
_uuid = uuidutils.generate_uuid
HOSTNAME = 'myhost'
FAKE_DIRECTOR = '1.1.1.1'
class TestBasicRouterOperations(base.BaseTestCase):
def setUp(self):
super(TestBasicRouterOperations, self).setUp()
self.conf = agent_config.setup_conf()
self.conf.register_opts(base_config.core_opts)
self.conf.register_opts(l3_config.OPTS)
self.conf.register_opts(ha.OPTS)
agent_config.register_process_monitor_opts(self.conf)
agent_config.register_interface_driver_opts_helper(self.conf)
self.conf.register_opts(interface.OPTS)
self.conf.set_override('interface_driver',
'neutron.agent.linux.interface.NullDriver')
self.conf.state_path = ''
self.device_exists_p = mock.patch(
'neutron.agent.linux.ip_lib.device_exists')
self.device_exists = self.device_exists_p.start()
self.utils_exec_p = mock.patch(
'neutron.agent.linux.utils.execute')
self.utils_exec = self.utils_exec_p.start()
self.external_process_p = mock.patch(
'neutron.agent.linux.external_process.ProcessManager')
self.external_process = self.external_process_p.start()
self.makedirs_p = mock.patch('os.makedirs')
self.makedirs = self.makedirs_p.start()
self.dvr_cls_p = mock.patch('neutron.agent.linux.interface.NullDriver')
driver_cls = self.dvr_cls_p.start()
self.mock_driver = mock.MagicMock()
self.mock_driver.DEV_NAME_LEN = (
interface.LinuxInterfaceDriver.DEV_NAME_LEN)
driver_cls.return_value = self.mock_driver
self.ip_cls_p = mock.patch('neutron.agent.linux.ip_lib.IPWrapper')
ip_cls = self.ip_cls_p.start()
self.mock_ip = mock.MagicMock()
ip_cls.return_value = self.mock_ip
mock.patch('neutron.agent.l3.agent.L3PluginApi').start()
self.looping_call_p = mock.patch(
'oslo_service.loopingcall.FixedIntervalLoopingCall')
self.looping_call_p.start()
self.fake_agent_mode = None
self.ri_kwargs = {'agent_conf': self.conf,
'interface_driver': self.mock_driver}
def _create_router(self):
router = varmour_router.vArmourL3NATAgent(HOSTNAME, self.conf)
router.rest.server = FAKE_DIRECTOR
router.rest.user = 'varmour'
router.rest.passwd = 'varmour'
return router
def _create_fwaas(self):
fwaas = varmour_fwaas.vArmourFwaasDriver()
fwaas.rest.server = FAKE_DIRECTOR
fwaas.rest.user = 'varmour'
fwaas.rest.passwd = 'varmour'
return fwaas
def _del_all_internal_ports(self, router):
router[l3_constants.INTERFACE_KEY] = []
def _del_internal_ports(self, router, port_idx):
del router[l3_constants.INTERFACE_KEY][port_idx]
def _add_internal_ports(self, router, port_count=1):
self._del_all_internal_ports(router)
for i in range(port_count):
port = {'id': _uuid(),
'network_id': _uuid(),
'admin_state_up': True,
'fixed_ips': [{'ip_address': '10.0.%s.4' % i,
'subnet_id': _uuid()}],
'mac_address': 'ca:fe:de:ad:be:ef',
'subnet': {'cidr': '10.0.%s.0/24' % i,
'gateway_ip': '10.0.%s.1' % i}}
router[l3_constants.INTERFACE_KEY].append(port)
def _del_all_floating_ips(self, router):
router[l3_constants.FLOATINGIP_KEY] = []
def _del_floating_ips(self, router, port_idx):
del router[l3_constants.FLOATINGIP_KEY][port_idx]
def _add_floating_ips(self, router, port_count=1):
self._del_all_floating_ips(router)
for i in range(port_count):
fip = {'id': _uuid(),
'port_id': router['gw_port']['id'],
'floating_ip_address': '172.24.4.%s' % (100 + i),
'fixed_ip_address': '10.0.0.%s' % (100 + i)}
router[l3_constants.FLOATINGIP_KEY].append(fip)
def _prepare_router_data(self, enable_snat=None):
router_id = _uuid()
ex_gw_port = {'id': _uuid(),
'network_id': _uuid(),
'fixed_ips': [{'ip_address': '172.24.4.2',
'subnet_id': _uuid()}],
'subnet': {'cidr': '172.24.4.0/24',
'gateway_ip': '172.24.4.1'},
'ip_cidr': '172.24.4.226/28'}
int_ports = []
router = {
'id': router_id,
l3_constants.INTERFACE_KEY: int_ports,
'routes': [],
'gw_port': ex_gw_port}
if enable_snat is not None:
router['enable_snat'] = enable_snat
ri = router_info.RouterInfo(router_id=router['id'], router=router,
**self.ri_kwargs)
return ri
def _add_firewall_rules(self, fw, rule_count=1):
rules = []
for i in range(rule_count):
rule = {'id': _uuid(),
'enabled': True,
'action': 'deny' if (i % 2 == 0) else 'allow',
'ip_version': 4,
'protocol': 'tcp',
'source_ip_address': '10.0.0.%s/24' % (100 + i),
'destination_port': '%s' % (100 + i)}
rules.append(rule)
fw['firewall_rule_list'] = rules
def _prepare_firewall_data(self):
fw = {'id': _uuid(),
'admin_state_up': True,
'firewall_rule_list': []}
return fw
def test_firewall_without_rule(self):
fwaas = self._create_fwaas()
fwaas.create_firewall = mock.Mock()
fwaas.delete_firewall = mock.Mock()
ri = self._prepare_router_data(enable_snat=True)
self._add_internal_ports(ri.router, port_count=1)
self._add_floating_ips(ri.router, port_count=1)
rl = [ri]
fw = self._prepare_firewall_data()
fwaas.create_firewall(self.fake_agent_mode, rl, fw)
fwaas.create_firewall.assert_called_once_with(self.fake_agent_mode,
rl, fw)
fwaas.delete_firewall(self.fake_agent_mode, rl, fw)
def test_firewall_with_rules(self):
fwaas = self._create_fwaas()
fwaas.create_firewall = mock.Mock()
fwaas.delete_firewall = mock.Mock()
fw = self._prepare_firewall_data()
self._add_firewall_rules(fw, 2)
ri = self._prepare_router_data(enable_snat=True)
self._add_internal_ports(ri.router, port_count=1)
self._add_floating_ips(ri.router, port_count=1)
rl = [ri]
fwaas.create_firewall(self.fake_agent_mode, rl, fw)
fwaas.create_firewall.assert_called_once_with(self.fake_agent_mode,
rl, fw)
fwaas.delete_firewall(self.fake_agent_mode, rl, fw)
def test_firewall_add_remove_rules(self):
fwaas = self._create_fwaas()
fwaas.create_firewall = mock.Mock()
fwaas.delete_firewall = mock.Mock()
fw = self._prepare_firewall_data()
ri = self._prepare_router_data(enable_snat=True)
self._add_internal_ports(ri.router, port_count=1)
self._add_floating_ips(ri.router, port_count=1)
rl = [ri]
self._add_firewall_rules(fw, 2)
fwaas.create_firewall(self.fake_agent_mode, rl, fw)
# 3x number of policies
self._add_firewall_rules(fw, 1)
fwaas.create_firewall(self.fake_agent_mode, rl, fw)
fwaas.delete_firewall(self.fake_agent_mode, rl, fw)
neutron-fwaas-8.0.0/neutron_fwaas/tests/unit/services/firewall/drivers/cisco/ 0000775 0005670 0005671 00000000000 12701410073 030646 5 ustar jenkins jenkins 0000000 0000000 neutron-fwaas-8.0.0/neutron_fwaas/tests/unit/services/firewall/drivers/cisco/test_csr_acl_driver.py 0000664 0005670 0005671 00000041605 12701407720 035253 0 ustar jenkins jenkins 0000000 0000000 # Copyright 2014 Cisco Systems, Inc. All rights reserved.
#
# 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.
import copy
import mock
import requests
import sys
from neutron.tests import base
with mock.patch.dict(sys.modules, {
'networking_cisco': mock.Mock(),
'networking_cisco.plugins': mock.Mock().plugins,
'networking_cisco.plugins.cisco': mock.Mock().cisco,
'networking_cisco.plugins.cisco.cfg_agent': mock.Mock().cfg_agent,
'networking_cisco.plugins.cisco.cfg_agent.device_drivers':
mock.Mock().device_drivers,
}):
from neutron_fwaas.services.firewall.drivers.cisco import csr_acl_driver
FAKE_ACL_ID = 'acl123'
FAKE_FW = {
'id': '123456789',
'admin_state_up': True,
'vendor_ext': {
'acl_id': FAKE_ACL_ID,
'host_mngt_ip': '192.169.101.5',
'host_usr_nm': 'lab',
'host_usr_pw': 'lab',
'if_list': [
{
'direction': 'inside',
'port': {
'id': 'fake_port_id',
'hosting_info': {
# map to interface GigabitEthernet3.101
'segmentation_id': 101,
'hosting_port_name': 't2_p:1',
},
},
},
]
},
'firewall_rule_list': [
{
'enabled': True,
'name': 'r1',
'ip_version': 4,
'protocol': 'tcp',
'action': 'allow',
'source_port': '3001',
'destination_port': '3001',
},
]
}
class TestCsrAclDriver(base.BaseTestCase):
def setUp(self):
super(TestCsrAclDriver, self).setUp()
self.csr = mock.Mock()
self.csracl = csr_acl_driver.CsrAclDriver()
self.csracl._get_csr_host = mock.Mock(return_value=self.csr)
self.acl_data = self.csracl._get_acl_rule_data(FAKE_FW)
self.aclapi_response = 'https://' + FAKE_FW[
'vendor_ext']['host_mngt_ip'] + '/' + FAKE_ACL_ID
def _set_csracl_mocks(self):
self.csracl._post_acl = mock.Mock()
self.csracl._post_acl_to_interfaces = mock.Mock()
self.csracl._delete_acl = mock.Mock()
self.csracl._put_acl = mock.Mock()
self.csracl._delete_acl_on_interface = mock.Mock()
self.csracl._get_acl_interface = mock.Mock()
def _set_csr_mocks(self):
self.csr.post_request = mock.Mock()
self.csr.delete_request = mock.Mock()
self.csr.get_request = mock.Mock()
self.csr.put_request = mock.Mock()
def _test_post_acl(self):
self._set_csr_mocks()
self.csr.post_request.return_value = self.aclapi_response
acl_id = self.csracl._post_acl(self.csr, self.acl_data)
self.csr.post_request.assert_called_once_with('acl', self.acl_data)
if self.csr.status == requests.codes.CREATED:
self.assertEqual(FAKE_ACL_ID, acl_id)
else:
self.assertEqual('', acl_id)
def test_post_acl_error(self):
self.csr.status = requests.codes.SERVER_ERROR
self._test_post_acl()
def test_post_acl(self):
self.csr.status = requests.codes.CREATED
self._test_post_acl()
def _test_delete_acl(self):
self._set_csr_mocks()
success = self.csracl._delete_acl(self.csr, FAKE_ACL_ID)
self.csr.delete_request.assert_called_once_with('acl/' + FAKE_ACL_ID)
if self.csr.status == requests.codes.NO_CONTENT:
self.assertTrue(success)
else:
self.assertFalse(success)
def test_delete_acl_error(self):
self.csr.status = requests.codes.SERVER_ERROR
self._test_delete_acl()
def test_delete_acl(self):
self.csr.status = requests.codes.NO_CONTENT
self._test_delete_acl()
def _test_put_acl(self):
self._set_csr_mocks()
success = self.csracl._put_acl(
self.csr, FAKE_ACL_ID, self.acl_data)
self.csr.put_request.assert_called_once_with(
'acl/' + FAKE_ACL_ID, self.acl_data)
if self.csr.status == requests.codes.NO_CONTENT:
self.assertTrue(success)
else:
self.assertFalse(success)
def test_put_acl_error(self):
self.csr.status = requests.codes.SERVER_ERROR
self._test_put_acl()
def test_put_acl(self):
self.csr.status = requests.codes.NO_CONTENT
self._test_put_acl()
def _test_post_acl_to_interfaces(self):
self._set_csr_mocks()
self.csr.post_request.return_value = 'fake_post_response'
status_data = {
'fw_id': FAKE_FW['id'],
'acl_id': FAKE_ACL_ID,
'if_list': []
}
firewall_interface = FAKE_FW['vendor_ext']['if_list'][0]
interface_name = self.csracl._get_interface_name_from_hosting_port(
firewall_interface['port'])
acl_interface_data = {
'if-id': interface_name,
'direction': firewall_interface['direction']}
api = 'acl/' + FAKE_ACL_ID + '/interfaces'
self.csracl._post_acl_to_interfaces(FAKE_FW, self.csr,
FAKE_ACL_ID, status_data)
self.csr.post_request.assert_called_once_with(api, acl_interface_data)
if self.csr.status == requests.codes.CREATED:
self.assertEqual(
[{'port_id': firewall_interface['port']['id'],
'status': 'OK'}],
status_data['if_list'])
else:
self.assertEqual(
[{'port_id': firewall_interface['port']['id'],
'status': 'ERROR'}],
status_data['if_list'])
def test_post_acl_to_interfaces_error(self):
self.csr.status = requests.codes.SERVER_ERROR
self._test_post_acl_to_interfaces()
def test_post_acl_to_interfaces(self):
self.csr.status = requests.codes.CREATED
self._test_post_acl_to_interfaces()
def test_delete_acl_on_interface(self):
self._set_csr_mocks()
self.csr.status = requests.codes.NO_CONTENT
csr_acl_interfaces = [
{
'acl-id': FAKE_ACL_ID,
'if-id': 'GigabitEthernet3.101',
'direction': 'inside'
}
]
api = 'acl/%s/interfaces/%s_%s' % (
FAKE_ACL_ID, csr_acl_interfaces[0]['if-id'],
csr_acl_interfaces[0]['direction'])
self.csracl._delete_acl_on_interface(
self.csr, FAKE_ACL_ID, csr_acl_interfaces)
self.csr.delete_request.assert_called_once_with(api)
def _test_get_acl_interface(self):
self._set_csr_mocks()
api = 'acl/%s/interfaces' % FAKE_ACL_ID
get_rsp = {'items': [{'fake_k1': 'fake_d1'}]}
self.csr.get_request.return_value = get_rsp
rsp = self.csracl._get_acl_interface(self.csr, FAKE_ACL_ID)
self.csr.get_request.assert_called_once_with(api)
if self.csr.status == requests.codes.OK:
self.assertEqual(get_rsp['items'], rsp)
else:
self.assertEqual('', rsp)
def test_get_acl_interface_err(self):
self.csr.status = requests.codes.SERVER_ERROR
self._test_get_acl_interface()
def test_get_acl_interface(self):
self.csr.status = requests.codes.OK
self._test_get_acl_interface()
def test_create_firewall_admin_state_not_up(self):
firewall = copy.deepcopy(FAKE_FW)
firewall['admin_state_up'] = False
self._set_csracl_mocks()
self.csracl._post_acl.return_value = FAKE_ACL_ID
success, status = self.csracl.create_firewall(None, None, firewall)
self.csracl._post_acl.assert_called_once_with(self.csr, self.acl_data)
self.assertTrue(success)
self.assertEqual(
{'fw_id': FAKE_FW['id'], 'acl_id': FAKE_ACL_ID, 'if_list': []},
status)
def test_create_firewall_post_acl_error(self):
self._set_csracl_mocks()
self.csracl._post_acl.return_value = ''
success, status = self.csracl.create_firewall(None, None, FAKE_FW)
self.csracl._post_acl.assert_called_once_with(self.csr, self.acl_data)
self.assertFalse(success)
def test_create_firewall(self):
self._set_csracl_mocks()
self.csracl._post_acl.return_value = FAKE_ACL_ID
status_data = {
'fw_id': FAKE_FW['id'],
'acl_id': FAKE_ACL_ID,
'if_list': []
}
success, status = self.csracl.create_firewall(None, None, FAKE_FW)
self.csracl._post_acl.assert_called_once_with(self.csr, self.acl_data)
self.csracl._post_acl_to_interfaces.assert_called_once_with(
FAKE_FW, self.csr, FAKE_ACL_ID, status_data)
self.assertTrue(success)
def _test_delete_firewall(self, delete_acl_success):
self._set_csracl_mocks()
self.csracl._delete_acl.return_value = delete_acl_success
success = self.csracl.delete_firewall(None, None, FAKE_FW)
self.csracl._delete_acl.assert_called_once_with(self.csr, FAKE_ACL_ID)
self.assertEqual(delete_acl_success, success)
def test_delete_firewall(self):
self._test_delete_firewall(True)
def test_delete_firewall_error(self):
self._test_delete_firewall(False)
def test_udpate_firewall_put_acl_error(self):
self._set_csracl_mocks()
self.csracl._put_acl.return_value = False
acldata = self.acl_data
acldata['acl-id'] = FAKE_ACL_ID
success, status = self.csracl.update_firewall(None, None, FAKE_FW)
self.csracl._put_acl.assert_called_once_with(
self.csr, FAKE_ACL_ID, acldata)
self.assertFalse(success)
def _test_update_firewall(self, admin_stat_up):
firewall = copy.deepcopy(FAKE_FW)
firewall['admin_state_up'] = admin_stat_up
self._set_csracl_mocks()
self.csracl._put_acl.return_value = True
acldata = self.acl_data
acldata['acl-id'] = FAKE_ACL_ID
fake_acl_interface_list = [{'if-id': 'GigabitEthernet3.101'}]
self.csracl._get_acl_interface.return_value = fake_acl_interface_list
status_data = {
'fw_id': firewall['id'],
'acl_id': FAKE_ACL_ID,
'if_list': []
}
success, status = self.csracl.update_firewall(None, None, firewall)
self.csracl._put_acl.assert_called_once_with(
self.csr, FAKE_ACL_ID, acldata)
self.csracl._get_acl_interface.assert_called_once_with(
self.csr, FAKE_ACL_ID)
self.csracl._delete_acl_on_interface.assert_called_once_with(
self.csr, FAKE_ACL_ID, fake_acl_interface_list)
self.assertTrue(success)
if not admin_stat_up:
self.assertEqual(status_data, status)
else:
self.csracl._post_acl_to_interfaces.assert_called_once_with(
firewall, self.csr, FAKE_ACL_ID, status_data)
def test_update_firewall_admin_state_not_up(self):
self._test_update_firewall(False)
def test_update_firewall(self):
self._test_update_firewall(True)
class TestCsrAclDriverValidation(base.BaseTestCase):
def setUp(self):
super(TestCsrAclDriverValidation, self).setUp()
self.csracl = csr_acl_driver.CsrAclDriver()
self.firewall = copy.deepcopy(FAKE_FW)
def test_create_firewall_no_admin_state(self):
del self.firewall['admin_state_up']
success, status = self.csracl.create_firewall(
None, None, self.firewall)
self.assertFalse(success)
def test_create_firewall_no_vendor_ext(self):
del self.firewall['vendor_ext']
success, status = self.csracl.create_firewall(
None, None, self.firewall)
self.assertFalse(success)
def test_create_firewall_no_host_mngt_ip(self):
del self.firewall['vendor_ext']['host_mngt_ip']
success, status = self.csracl.create_firewall(
None, None, self.firewall)
self.assertFalse(success)
def test_create_firewall_no_host_usr_name(self):
del self.firewall['vendor_ext']['host_usr_nm']
success, status = self.csracl.create_firewall(
None, None, self.firewall)
self.assertFalse(success)
def test_create_firewall_no_host_usr_password(self):
del self.firewall['vendor_ext']['host_usr_pw']
success, status = self.csracl.create_firewall(
None, None, self.firewall)
self.assertFalse(success)
def test_create_firewall_no_if_list(self):
del self.firewall['vendor_ext']['if_list']
success, status = self.csracl.create_firewall(
None, None, self.firewall)
self.assertFalse(success)
def test_create_firewall_no_direction(self):
del self.firewall['vendor_ext']['if_list'][0]['direction']
success, status = self.csracl.create_firewall(
None, None, self.firewall)
self.assertFalse(success)
def test_create_firewall_invalid_direction(self):
self.firewall['vendor_ext']['if_list'][0]['direction'] = 'dir'
success, status = self.csracl.create_firewall(
None, None, self.firewall)
self.assertFalse(success)
def test_create_firewall_no_port(self):
del self.firewall['vendor_ext']['if_list'][0]['port']
success, status = self.csracl.create_firewall(
None, None, self.firewall)
self.assertFalse(success)
def test_create_firewall_no_host_info(self):
del self.firewall['vendor_ext']['if_list'][0]['port']['hosting_info']
success, status = self.csracl.create_firewall(
None, None, self.firewall)
self.assertFalse(success)
def test_create_firewall_no_segmentation_id(self):
del self.firewall['vendor_ext']['if_list'][0]['port']['hosting_info'][
'segmentation_id']
success, status = self.csracl.create_firewall(
None, None, self.firewall)
self.assertFalse(success)
def test_create_firewall_no_host_port_name(self):
del self.firewall['vendor_ext']['if_list'][0]['port']['hosting_info'][
'hosting_port_name']
success, status = self.csracl.create_firewall(
None, None, self.firewall)
self.assertFalse(success)
def test_create_firewall_invalid_host_port_name(self):
self.firewall['vendor_ext']['if_list'][0]['port']['hosting_info'][
'hosting_port_name'] = 't3_p:1'
success, status = self.csracl.create_firewall(
None, None, self.firewall)
self.assertFalse(success)
def test_create_firewall_no_rule_list(self):
del self.firewall['firewall_rule_list']
success, status = self.csracl.create_firewall(
None, None, self.firewall)
self.assertFalse(success)
def test_create_firewall_rule_no_name(self):
del self.firewall['firewall_rule_list'][0]['name']
success, status = self.csracl.create_firewall(
None, None, self.firewall)
self.assertFalse(success)
def test_create_firewall_rule_no_ip_version(self):
del self.firewall['firewall_rule_list'][0]['ip_version']
success, status = self.csracl.create_firewall(
None, None, self.firewall)
self.assertFalse(success)
def test_create_firewall_rule_not_ipv4(self):
self.firewall['firewall_rule_list'][0]['ip_version'] = 6
success, status = self.csracl.create_firewall(
None, None, self.firewall)
self.assertFalse(success)
def test_create_firewall_rule_no_protocol(self):
del self.firewall['firewall_rule_list'][0]['protocol']
success, status = self.csracl.create_firewall(
None, None, self.firewall)
self.assertFalse(success)
def test_create_firewall_rule_no_action(self):
del self.firewall['firewall_rule_list'][0]['action']
success, status = self.csracl.create_firewall(
None, None, self.firewall)
self.assertFalse(success)
def test_create_firewall_rule_invalid_action(self):
self.firewall['firewall_rule_list'][0]['action'] = 'action'
success, status = self.csracl.create_firewall(
None, None, self.firewall)
self.assertFalse(success)
def test_update_firewall_no_acl_id(self):
del self.firewall['vendor_ext']['acl_id']
success, status = self.csracl.update_firewall(
None, None, self.firewall)
self.assertFalse(success)
def test_delete_firewall_no_acl_id(self):
del self.firewall['vendor_ext']['acl_id']
success = self.csracl.delete_firewall(None, None, self.firewall)
self.assertFalse(success)
neutron-fwaas-8.0.0/neutron_fwaas/tests/unit/services/firewall/drivers/cisco/__init__.py 0000664 0005670 0005671 00000000000 12701407720 032752 0 ustar jenkins jenkins 0000000 0000000 ././@LongLink 0000000 0000000 0000000 00000000155 00000000000 011216 L ustar 0000000 0000000 neutron-fwaas-8.0.0/neutron_fwaas/tests/unit/services/firewall/drivers/cisco/test_csr_firewall_svc_helper.py neutron-fwaas-8.0.0/neutron_fwaas/tests/unit/services/firewall/drivers/cisco/test_csr_firewall_svc_h0000664 0005670 0005671 00000022665 12701407720 035506 0 ustar jenkins jenkins 0000000 0000000 # Copyright 2014 Cisco Systems, Inc. All rights reserved.
#
# 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.
import mock
import sys
from neutron import context as n_context
from neutron.plugins.common import constants
from neutron.tests import base
# Mocking imports of 3rd party cisco library in unit tests and all modules
# that depends on this library.
with mock.patch.dict(sys.modules, {
'networking_cisco': mock.Mock(),
'networking_cisco.plugins': mock.Mock().plugins,
'networking_cisco.plugins.cisco': mock.Mock().cisco,
'networking_cisco.plugins.cisco.cfg_agent': mock.Mock().cfg_agent,
'networking_cisco.plugins.cisco.cfg_agent.device_drivers':
mock.Mock().device_drivers,
'networking_cisco.plugins.cisco.cfg_agent.service_helpers':
mock.Mock().service_helpers,
}):
from neutron_fwaas.services.firewall.drivers.cisco import (
csr_firewall_svc_helper)
HOST = 'myhost'
FAKE_FW = {'id': '1234'}
FAKE_FW_STATUS = {
'fw_id': '1234',
'acl_id': 'acl123',
'if_list': []
}
class TestCsrFirewallServiceHelper(base.BaseTestCase):
def setUp(self):
super(TestCsrFirewallServiceHelper, self).setUp()
self.firewall_plugin_api_cls_p = mock.patch(
'neutron_fwaas.services.firewall.drivers.cisco.'
'csr_firewall_svc_helper.CsrFirewalllPluginApi')
self.firewall_plugin_api_cls = self.firewall_plugin_api_cls_p.start()
self.firewall_plugin_api = mock.Mock()
self.firewall_plugin_api_cls.return_value = self.firewall_plugin_api
self.firewall_plugin_api.get_firewalls_for_device = mock.MagicMock()
self.firewall_plugin_api.get_firewalls_for_tenant = mock.MagicMock()
self.firewall_plugin_api.get_tenants_with_firewalls = mock.MagicMock()
self.firewall_plugin_api.firewall_deleted = mock.MagicMock()
self.firewall_plugin_api.set_firewall_status = mock.MagicMock()
mock.patch('neutron.common.rpc.create_connection').start()
self.fw_svc_helper = csr_firewall_svc_helper.CsrFirewallServiceHelper(
HOST, mock.Mock(), mock.Mock())
self.fw_svc_helper.acl_driver = mock.Mock()
self.fw_svc_helper.event_q = mock.Mock()
self.fw_svc_helper.event_q.enqueue = mock.Mock()
self.ctx = mock.Mock()
def _test_firewall_even_enqueue(self, event_name):
firewall_event = {'event': event_name,
'context': self.ctx,
'firewall': FAKE_FW,
'host': HOST}
self.fw_svc_helper.event_q.enqueue.assert_called_with(
'csr_fw_event_q', firewall_event)
def test_create_firewall(self):
self.fw_svc_helper.create_firewall(self.ctx, FAKE_FW, HOST)
self._test_firewall_even_enqueue('FW_EVENT_CREATE')
def test_update_firewall(self):
self.fw_svc_helper.update_firewall(self.ctx, FAKE_FW, HOST)
self._test_firewall_even_enqueue('FW_EVENT_UPDATE')
def test_delete_firewall(self):
self.fw_svc_helper.delete_firewall(self.ctx, FAKE_FW, HOST)
self._test_firewall_even_enqueue('FW_EVENT_DELETE')
def _test_fullsync(self, firewall_status, function_name):
self.fw_svc_helper._invoke_firewall_driver = mock.Mock()
self.fw_svc_helper.fullsync = True
self.firewall_plugin_api.get_tenants_with_firewalls.return_value = [
'1']
firewall = FAKE_FW
firewall['status'] = firewall_status
self.firewall_plugin_api.get_firewalls_for_tenant.return_value = [
firewall]
ctx_p = mock.patch.object(n_context, 'Context').start()
ctx_p.return_value = self.ctx
self.fw_svc_helper.process_service()
self.fw_svc_helper._invoke_firewall_driver.assert_called_with(
self.ctx, firewall, function_name)
self.assertFalse(self.fw_svc_helper.fullsync)
def test_proc_service_fullsync_firewall_pending_create(self):
self._test_fullsync('PENDING_CREATE', 'create_firewall')
def test_proc_service_fullsync_firewall_pending_update(self):
self._test_fullsync('PENDING_UPDATE', 'update_firewall')
def test_proc_service_fullsync_frewall_pending_delete(self):
self._test_fullsync('PENDING_DELETE', 'delete_firewall')
def _test_proc_service_device_ids(self, firewall_status, function_name):
self.fw_svc_helper._invoke_firewall_driver = mock.Mock()
self.fw_svc_helper.fullsync = False
ctx_p = mock.patch.object(n_context, 'Context').start()
ctx_p.return_value = self.ctx
firewall = FAKE_FW
firewall['status'] = firewall_status
self.firewall_plugin_api.get_firewalls_for_device.return_value = [
firewall]
self.fw_svc_helper.process_service(device_ids=['123'])
self.fw_svc_helper._invoke_firewall_driver.assert_called_with(
self.ctx, firewall, function_name)
def test_proc_service_device_ids_firewall_pending_create(self):
self._test_proc_service_device_ids(
'PENDING_CREATE', 'create_firewall')
def test_proc_service_device_ids_firewall_pending_update(self):
self._test_proc_service_device_ids(
'PENDING_UPDATE', 'update_firewall')
def test_proc_service_device_ids_firewall_pending_delete(self):
self._test_proc_service_device_ids(
'PENDING_DELETE', 'delete_firewall')
def _test_firewall_event(self, event, function_name):
self.fw_svc_helper._invoke_firewall_driver = mock.Mock()
self.fw_svc_helper.fullsync = False
event_data = {'event': event, 'context': self.ctx,
'firewall': FAKE_FW, 'host': HOST}
event_q_returns = [event_data, None]
def _ev_dequeue_side_effect(*args):
return event_q_returns.pop(0)
self.fw_svc_helper.event_q.dequeue = mock.Mock(
side_effect=_ev_dequeue_side_effect)
self.fw_svc_helper.process_service()
self.fw_svc_helper._invoke_firewall_driver.assert_called_once_with(
self.ctx, FAKE_FW, function_name)
def test_proc_service_firewall_event_create(self):
self._test_firewall_event('FW_EVENT_CREATE', 'create_firewall')
def test_proc_service_firewall_event_update(self):
self._test_firewall_event('FW_EVENT_UPDATE', 'update_firewall')
def test_proc_service_firewall_event_delete(self):
self._test_firewall_event('FW_EVENT_DELETE', 'delete_firewall')
def test_invoke_firewall_driver_for_delete(self):
self.fw_svc_helper.acl_driver.delete_firewall = mock.Mock()
self.fw_svc_helper.acl_driver.delete_firewall.return_value = True
self.fw_svc_helper._invoke_firewall_driver(
self.ctx, FAKE_FW, 'delete_firewall')
self.fw_svc_helper.acl_driver.delete_firewall.assert_called_with(
None, None, FAKE_FW)
self.firewall_plugin_api.firewall_deleted.assert_called_with(
self.ctx, FAKE_FW['id'])
self.fw_svc_helper.acl_driver.delete_firewall.return_value = False
self.fw_svc_helper._invoke_firewall_driver(
self.ctx, FAKE_FW, 'delete_firewall')
self.firewall_plugin_api.set_firewall_status.assert_called_with(
self.ctx, FAKE_FW['id'], constants.ERROR)
def test_invoke_firewall_driver_for_create(self):
self.fw_svc_helper.acl_driver.create_firewall = mock.Mock()
self.fw_svc_helper.acl_driver.create_firewall.return_value = (
True, FAKE_FW_STATUS)
self.fw_svc_helper._invoke_firewall_driver(
self.ctx, FAKE_FW, 'create_firewall')
self.fw_svc_helper.acl_driver.create_firewall.assert_called_with(
None, None, FAKE_FW)
self.firewall_plugin_api.set_firewall_status.assert_called_with(
self.ctx, FAKE_FW['id'], constants.ACTIVE, FAKE_FW_STATUS)
self.fw_svc_helper.acl_driver.create_firewall.return_value = (
False, {})
self.fw_svc_helper._invoke_firewall_driver(
self.ctx, FAKE_FW, 'create_firewall')
self.firewall_plugin_api.set_firewall_status.assert_called_with(
self.ctx, FAKE_FW['id'], constants.ERROR)
def test_invoke_firewall_driver_for_update(self):
self.fw_svc_helper.acl_driver.update_firewall = mock.Mock()
self.fw_svc_helper.acl_driver.update_firewall.return_value = (
True, FAKE_FW_STATUS)
self.fw_svc_helper._invoke_firewall_driver(
self.ctx, FAKE_FW, 'update_firewall')
self.fw_svc_helper.acl_driver.update_firewall.assert_called_with(
None, None, FAKE_FW)
self.firewall_plugin_api.set_firewall_status.assert_called_with(
self.ctx, FAKE_FW['id'], constants.ACTIVE, FAKE_FW_STATUS)
self.fw_svc_helper.acl_driver.update_firewall.return_value = (
False, {})
self.fw_svc_helper._invoke_firewall_driver(
self.ctx, FAKE_FW, 'update_firewall')
self.firewall_plugin_api.set_firewall_status.assert_called_with(
self.ctx, FAKE_FW['id'], constants.ERROR)
neutron-fwaas-8.0.0/neutron_fwaas/tests/unit/services/firewall/drivers/__init__.py 0000664 0005670 0005671 00000000000 12701407720 031652 0 ustar jenkins jenkins 0000000 0000000 neutron-fwaas-8.0.0/neutron_fwaas/tests/unit/services/firewall/drivers/vyatta/ 0000775 0005670 0005671 00000000000 12701410073 031056 5 ustar jenkins jenkins 0000000 0000000 neutron-fwaas-8.0.0/neutron_fwaas/tests/unit/services/firewall/drivers/vyatta/__init__.py 0000664 0005670 0005671 00000000000 12701407720 033162 0 ustar jenkins jenkins 0000000 0000000 neutron-fwaas-8.0.0/neutron_fwaas/tests/unit/services/firewall/drivers/vyatta/test_vyatta_fwaas.py 0000664 0005670 0005671 00000023241 12701407720 035167 0 ustar jenkins jenkins 0000000 0000000 # Copyright 2015 OpenStack Foundation.
# All Rights Reserved.
#
# 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.
import sys
import mock
from neutron.tests import base
from oslo_utils import uuidutils
from six.moves.urllib import parse
# Mocking imports of 3rd party vyatta library in unit tests and all modules
# that depends on this library. Import will fail if not mocked and 3rd party
# vyatta library is not installed.
with mock.patch.dict(sys.modules, {
'networking_brocade': mock.Mock(),
'networking_brocade.vyatta': mock.Mock(),
'networking_brocade.vyatta.common': mock.Mock(),
'networking_brocade.vyatta.vrouter': mock.Mock(),
}):
from networking_brocade.vyatta.vrouter import client as vyatta_client
from neutron_fwaas.services.firewall.agents.vyatta import vyatta_utils
from neutron_fwaas.services.firewall.drivers.vyatta import vyatta_fwaas
_uuid = uuidutils.generate_uuid
FAKE_FW_UUID = _uuid()
def fake_cmd(*args, **kwargs):
return (args, kwargs)
class VyattaFwaasTestCase(base.BaseTestCase):
def setUp(self):
super(VyattaFwaasTestCase, self).setUp()
mock.patch.object(vyatta_client, 'SetCmd', fake_cmd).start()
mock.patch.object(vyatta_client, 'DeleteCmd', fake_cmd).start()
self.fwaas_driver = vyatta_fwaas.VyattaFirewallDriver()
self.fake_rules = [self._make_fake_fw_rule()]
self.fake_firewall = self._make_fake_firewall(self.fake_rules)
self.fake_firewall_name = vyatta_utils.get_firewall_name(
None, self.fake_firewall)
self.fake_apply_list = [self._make_fake_router_info()]
self.fake_agent_mode = None
def test_create_firewall(self):
with mock.patch.object(
self.fwaas_driver, 'update_firewall') as fw_update:
self.fwaas_driver.create_firewall(
self.fake_agent_mode, self.fake_apply_list, self.fake_firewall)
fw_update.assert_called_once_with(
self.fake_agent_mode, self.fake_apply_list, self.fake_firewall)
def test_update_firewall(self):
with mock.patch.object(
self.fwaas_driver, '_update_firewall') as fw_update:
self.fake_firewall['admin_state_up'] = True
self.fwaas_driver.create_firewall(
self.fake_agent_mode, self.fake_apply_list, self.fake_firewall)
fw_update.assert_called_once_with(
self.fake_apply_list, self.fake_firewall)
with mock.patch.object(
self.fwaas_driver, 'apply_default_policy') as fw_apply_policy:
self.fake_firewall['admin_state_up'] = False
self.fwaas_driver.create_firewall(
self.fake_agent_mode, self.fake_apply_list, self.fake_firewall)
fw_apply_policy.assert_called_once_with(
self.fake_agent_mode, self.fake_apply_list, self.fake_firewall)
def test_delete_firewall(self):
with mock.patch.object(
self.fwaas_driver, 'apply_default_policy') as fw_apply_policy:
self.fwaas_driver.delete_firewall(
self.fake_agent_mode, self.fake_apply_list, self.fake_firewall)
fw_apply_policy.assert_called_once_with(
self.fake_agent_mode, self.fake_apply_list, self.fake_firewall)
def test_apply_default_policy(self):
with mock.patch.object(
self.fwaas_driver, '_delete_firewall') as fw_delete:
self.fwaas_driver.apply_default_policy(
self.fake_agent_mode, self.fake_apply_list, self.fake_firewall)
calls = [mock.call(x, self.fake_firewall)
for x in self.fake_apply_list]
fw_delete.assert_has_calls(calls)
def test_update_firewall_internal(self):
with mock.patch.object(
self.fwaas_driver, '_delete_firewall'
) as fw_delete, mock.patch.object(
self.fwaas_driver, '_setup_firewall') as fw_setup:
self.fwaas_driver._update_firewall(
self.fake_apply_list, self.fake_firewall)
calls = [mock.call(x, self.fake_firewall)
for x in self.fake_apply_list]
fw_delete.assert_has_calls(calls)
fw_setup.assert_has_calls(calls)
def test_setup_firewall_internal(self):
fake_rule = self._make_fake_fw_rule()
fake_router_info = self._make_fake_router_info()
fake_rule_cmd = 'fake-fw-rule0'
fake_zone_configure_rules = ['fake-config-rule0']
mock_api = mock.Mock()
mock_api_gen = mock.Mock(return_value=mock_api)
mock_get_firewall_rule = mock.Mock(return_value=[fake_rule_cmd])
mock_get_zone_cmds = mock.Mock(return_value=fake_zone_configure_rules)
with mock.patch.object(self.fwaas_driver, '_get_vyatta_client',
mock_api_gen), \
mock.patch.object(vyatta_fwaas.vyatta_utils, 'get_zone_cmds',
mock_get_zone_cmds), \
mock.patch.object(self.fwaas_driver, '_set_firewall_rule',
mock_get_firewall_rule):
self.fwaas_driver._setup_firewall(
fake_router_info, self.fake_firewall)
mock_api_gen.assert_called_once_with(
fake_router_info.router)
mock_get_firewall_rule.assert_called_once_with(
self.fake_firewall_name, 1, fake_rule)
mock_get_zone_cmds.assert_called_once_with(
mock_api, fake_router_info, self.fake_firewall_name)
cmds = [
vyatta_client.SetCmd(
vyatta_fwaas.FW_NAME.format(
self.fake_firewall_name)),
vyatta_client.SetCmd(
vyatta_fwaas.FW_DESCRIPTION.format(
self.fake_firewall_name,
parse.quote_plus(self.fake_firewall['description']))),
vyatta_client.SetCmd(
vyatta_fwaas.FW_ESTABLISHED_ACCEPT),
vyatta_client.SetCmd(
vyatta_fwaas.FW_RELATED_ACCEPT),
fake_rule_cmd,
] + fake_zone_configure_rules
mock_api.exec_cmd_batch.assert_called_once_with(cmds)
def test_delete_firewall_internal(self):
fake_router_info = self._make_fake_router_info()
with mock.patch.object(
self.fwaas_driver,
'_get_vyatta_client') as mock_client_factory:
mock_api = mock_client_factory.return_value
self.fwaas_driver._delete_firewall(
fake_router_info, self.fake_firewall)
cmds = [
vyatta_client.DeleteCmd("zone-policy"),
vyatta_client.DeleteCmd(vyatta_fwaas.FW_NAME.format(
self.fake_firewall_name)),
vyatta_client.DeleteCmd("firewall/state-policy"),
]
mock_api.exec_cmd_batch.assert_called_once_with(cmds)
def test_set_firewall_rule_internal(self):
fake_rule = self._make_fake_fw_rule()
fake_firewall_name = 'fake-fw-name'
fake_rule.update({
'description': 'rule description',
'source_port': '2080',
'destination_ip_address': '172.16.1.1'
})
action_map = {
'allow': 'accept',
}
cmds_actual = self.fwaas_driver._set_firewall_rule(
fake_firewall_name, 1, fake_rule)
cmds_expect = [
vyatta_client.SetCmd(
vyatta_fwaas.FW_RULE_DESCRIPTION.format(
parse.quote_plus(fake_firewall_name), 1,
parse.quote_plus(fake_rule['description'])))
]
rules = [
('protocol', vyatta_fwaas.FW_RULE_PROTOCOL),
('source_port', vyatta_fwaas.FW_RULE_SRC_PORT),
('destination_port', vyatta_fwaas.FW_RULE_DEST_PORT),
('source_ip_address', vyatta_fwaas.FW_RULE_SRC_ADDR),
('destination_ip_address', vyatta_fwaas.FW_RULE_DEST_ADDR),
]
for key, url in rules:
cmds_expect.append(vyatta_client.SetCmd(
url.format(
parse.quote_plus(fake_firewall_name), 1,
parse.quote_plus(fake_rule[key]))))
cmds_expect.append(vyatta_client.SetCmd(
vyatta_fwaas.FW_RULE_ACTION.format(
parse.quote_plus(fake_firewall_name), 1,
action_map.get(fake_rule['action'], 'drop'))))
self.assertEqual(cmds_expect, cmds_actual)
def _make_fake_router_info(self):
info = mock.Mock()
info.router = {
'id': 'fake-router-id',
'tenant_id': 'tenant-uuid',
}
return info
def _make_fake_fw_rule(self):
return {
'enabled': True,
'action': 'allow',
'ip_version': 4,
'protocol': 'tcp',
'destination_port': '80',
'source_ip_address': '10.24.4.2'}
def _make_fake_firewall(self, rules):
return {'id': FAKE_FW_UUID,
'admin_state_up': True,
'name': 'test-firewall',
'tenant_id': 'tenant-uuid',
'description': 'Fake firewall',
'firewall_rule_list': rules}
neutron-fwaas-8.0.0/neutron_fwaas/tests/unit/services/firewall/agents/ 0000775 0005670 0005671 00000000000 12701410073 027351 5 ustar jenkins jenkins 0000000 0000000 neutron-fwaas-8.0.0/neutron_fwaas/tests/unit/services/firewall/agents/test_firewall_agent_api.py 0000664 0005670 0005671 00000004733 12701407720 034612 0 ustar jenkins jenkins 0000000 0000000 # Copyright (c) 2013 OpenStack Foundation
# All Rights Reserved.
#
# 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.
import mock
from neutron_fwaas.services.firewall.agents import firewall_agent_api as api
from neutron_fwaas.services.firewall.drivers import fwaas_base as base_driver
from neutron_fwaas.tests import base
class NoopFwaasDriver(base_driver.FwaasDriverBase):
"""Noop Fwaas Driver.
Firewall driver which does nothing.
This driver is for disabling Fwaas functionality.
"""
def create_firewall(self, agent_mode, apply_list, firewall):
pass
def delete_firewall(self, agent_mode, apply_list, firewall):
pass
def update_firewall(self, agent_mode, apply_list, firewall):
pass
def apply_default_policy(self, agent_mode, apply_list, firewall):
pass
class TestFWaaSAgentApi(base.BaseTestCase):
def setUp(self):
super(TestFWaaSAgentApi, self).setUp()
self.api = api.FWaaSPluginApiMixin(
'topic',
'host')
def test_init(self):
self.assertEqual('host', self.api.host)
def _test_firewall_method(self, method_name, **kwargs):
with mock.patch.object(self.api.client, 'call') as rpc_mock, \
mock.patch.object(self.api.client, 'prepare') as prepare_mock:
prepare_mock.return_value = self.api.client
getattr(self.api, method_name)(mock.sentinel.context, 'test',
**kwargs)
prepare_args = {}
prepare_mock.assert_called_once_with(**prepare_args)
rpc_mock.assert_called_once_with(mock.sentinel.context, method_name,
firewall_id='test', host='host',
**kwargs)
def test_set_firewall_status(self):
self._test_firewall_method('set_firewall_status', status='fake_status')
def test_firewall_deleted(self):
self._test_firewall_method('firewall_deleted')
neutron-fwaas-8.0.0/neutron_fwaas/tests/unit/services/firewall/agents/l3reference/ 0000775 0005670 0005671 00000000000 12701410073 031546 5 ustar jenkins jenkins 0000000 0000000 ././@LongLink 0000000 0000000 0000000 00000000154 00000000000 011215 L ustar 0000000 0000000 neutron-fwaas-8.0.0/neutron_fwaas/tests/unit/services/firewall/agents/l3reference/test_firewall_l3_agent.py neutron-fwaas-8.0.0/neutron_fwaas/tests/unit/services/firewall/agents/l3reference/test_firewall_l3_a0000664 0005670 0005671 00000035154 12701407720 035250 0 ustar jenkins jenkins 0000000 0000000 # Copyright (c) 2013 OpenStack Foundation
# All Rights Reserved.
# 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.
import uuid
import mock
from oslo_config import cfg
from neutron.agent.l3 import config as l3_config
from neutron.agent.l3 import ha
from neutron.agent.l3 import router_info
from neutron.agent.linux import ip_lib
from neutron.common import config as base_config
from neutron import context
from neutron.plugins.common import constants
from neutron_fwaas.services.firewall.agents import firewall_agent_api
from neutron_fwaas.services.firewall.agents.l3reference \
import firewall_l3_agent
from neutron_fwaas.tests import base
from neutron_fwaas.tests.unit.services.firewall.agents \
import test_firewall_agent_api
class FWaasHelper(object):
def __init__(self, host):
pass
class FWaasAgent(firewall_l3_agent.FWaaSL3AgentRpcCallback, FWaasHelper):
neutron_service_plugins = []
def _setup_test_agent_class(service_plugins):
class FWaasTestAgent(firewall_l3_agent.FWaaSL3AgentRpcCallback,
FWaasHelper):
neutron_service_plugins = service_plugins
def __init__(self, conf):
self.event_observers = mock.Mock()
self.conf = conf
super(FWaasTestAgent, self).__init__(conf)
return FWaasTestAgent
class TestFwaasL3AgentRpcCallback(base.BaseTestCase):
def setUp(self):
super(TestFwaasL3AgentRpcCallback, self).setUp()
self.conf = cfg.ConfigOpts()
self.conf.register_opts(base_config.core_opts)
self.conf.register_opts(l3_config.OPTS)
self.conf.register_opts(ha.OPTS)
self.conf.register_opts(firewall_agent_api.FWaaSOpts, 'fwaas')
self.api = FWaasAgent(self.conf)
self.api.fwaas_driver = test_firewall_agent_api.NoopFwaasDriver()
self.adminContext = context.get_admin_context()
self.router_id = str(uuid.uuid4())
self.agent_conf = mock.Mock()
self.ri_kwargs = {'router': {'id': self.router_id,
'tenant_id': str(uuid.uuid4())},
'agent_conf': self.agent_conf,
'interface_driver': mock.ANY,
'use_ipv6': mock.ANY,
}
def test_fw_config_match(self):
test_agent_class = _setup_test_agent_class([constants.FIREWALL])
cfg.CONF.set_override('enabled', True, 'fwaas')
with mock.patch('oslo_utils.importutils.import_object'):
test_agent_class(cfg.CONF)
def test_fw_config_mismatch_plugin_enabled_agent_disabled(self):
test_agent_class = _setup_test_agent_class([constants.FIREWALL])
cfg.CONF.set_override('enabled', False, 'fwaas')
self.assertRaises(SystemExit, test_agent_class, cfg.CONF)
def test_fw_plugin_list_unavailable(self):
test_agent_class = _setup_test_agent_class(None)
cfg.CONF.set_override('enabled', False, 'fwaas')
with mock.patch('oslo_utils.importutils.import_object'):
test_agent_class(cfg.CONF)
def test_create_firewall(self):
fake_firewall = {'id': 0, 'tenant_id': 1,
'admin_state_up': True,
'add-router-ids': [1, 2]}
self.api.plugin_rpc = mock.Mock()
with mock.patch.object(self.api, '_get_router_info_list_for_tenant'
) as mock_get_router_info_list_for_tenant, \
mock.patch.object(self.api.fwaas_driver, 'create_firewall'
) as mock_driver_create_firewall, \
mock.patch.object(self.api.fwplugin_rpc, 'set_firewall_status'
) as mock_set_firewall_status:
mock_driver_create_firewall.return_value = True
self.api.create_firewall(
context=mock.sentinel.context,
firewall=fake_firewall, host='host')
mock_get_router_info_list_for_tenant.assert_called_once_with(
fake_firewall['add-router-ids'], fake_firewall['tenant_id'])
mock_set_firewall_status.assert_called_once_with(
mock.sentinel.context,
fake_firewall['id'],
'ACTIVE')
def test_update_firewall_with_routers_added_and_deleted(self):
fake_firewall = {'id': 0, 'tenant_id': 1,
'admin_state_up': True,
'add-router-ids': [1, 2],
'del-router-ids': [3, 4],
'router_ids': [],
'last-router': False}
self.api.plugin_rpc = mock.Mock()
with mock.patch.object(self.api, '_get_router_info_list_for_tenant'
) as mock_get_router_info_list_for_tenant, \
mock.patch.object(self.api.fwaas_driver, 'update_firewall'
) as mock_driver_delete_firewall, \
mock.patch.object(self.api.fwaas_driver, 'delete_firewall'
) as mock_driver_update_firewall, \
mock.patch.object(self.api.fwplugin_rpc, 'set_firewall_status'
) as mock_set_firewall_status:
mock_driver_delete_firewall.return_value = True
mock_driver_update_firewall.return_value = True
calls = [mock.call(fake_firewall['del-router-ids'],
fake_firewall['tenant_id']),
mock.call(fake_firewall['add-router-ids'],
fake_firewall['tenant_id'])]
self.api.update_firewall(
context=mock.sentinel.context,
firewall=fake_firewall, host='host')
self.assertEqual(
mock_get_router_info_list_for_tenant.call_args_list,
calls)
mock_set_firewall_status.assert_called_once_with(
mock.sentinel.context,
fake_firewall['id'],
'ACTIVE')
def test_update_firewall_with_routers_added_and_admin_state_down(self):
fake_firewall = {'id': 0, 'tenant_id': 1,
'admin_state_up': False,
'add-router-ids': [1, 2],
'del-router-ids': [],
'router_ids': [],
'last-router': False}
self.api.plugin_rpc = mock.Mock()
with mock.patch.object(self.api, '_get_router_info_list_for_tenant'
) as mock_get_router_info_list_for_tenant, \
mock.patch.object(self.api.fwaas_driver, 'update_firewall'
) as mock_driver_update_firewall, \
mock.patch.object(self.api.fwplugin_rpc, 'set_firewall_status'
) as mock_set_firewall_status:
mock_driver_update_firewall.return_value = True
self.api.update_firewall(
context=mock.sentinel.context,
firewall=fake_firewall, host='host')
mock_get_router_info_list_for_tenant.assert_called_once_with(
fake_firewall['add-router-ids'], fake_firewall['tenant_id'])
mock_set_firewall_status.assert_called_once_with(
mock.sentinel.context,
fake_firewall['id'],
'DOWN')
def test_update_firewall_with_all_routers_deleted(self):
fake_firewall = {'id': 0, 'tenant_id': 1,
'admin_state_up': True,
'add-router-ids': [],
'del-router-ids': [3, 4],
'last-router': True}
self.api.plugin_rpc = mock.Mock()
with mock.patch.object(self.api, '_get_router_info_list_for_tenant'
) as mock_get_router_info_list_for_tenant, \
mock.patch.object(self.api.fwaas_driver, 'delete_firewall'
) as mock_driver_delete_firewall, \
mock.patch.object(self.api.fwplugin_rpc, 'set_firewall_status'
) as mock_set_firewall_status:
mock_driver_delete_firewall.return_value = True
self.api.update_firewall(
context=mock.sentinel.context,
firewall=fake_firewall, host='host')
mock_get_router_info_list_for_tenant.assert_called_once_with(
fake_firewall['del-router-ids'], fake_firewall['tenant_id'])
mock_set_firewall_status.assert_called_once_with(
mock.sentinel.context,
fake_firewall['id'],
'INACTIVE')
def test_update_firewall_with_rtrs_and_no_rtrs_added_nor_deleted(self):
fake_firewall = {'id': 0, 'tenant_id': 1,
'admin_state_up': True,
'add-router-ids': [],
'del-router-ids': [],
'router_ids': [1, 2]}
self.api.plugin_rpc = mock.Mock()
with mock.patch.object(self.api.fwaas_driver, 'update_firewall'
) as mock_driver_update_firewall, \
mock.patch.object(self.api, '_get_router_info_list_for_tenant'
) as mock_get_router_info_list_for_tenant, \
mock.patch.object(self.api.fwplugin_rpc, 'set_firewall_status'
) as mock_set_firewall_status:
mock_driver_update_firewall.return_value = True
self.api.update_firewall(
context=mock.sentinel.context,
firewall=fake_firewall, host='host')
mock_get_router_info_list_for_tenant.assert_called_once_with(
fake_firewall['router_ids'], fake_firewall['tenant_id'])
mock_set_firewall_status.assert_called_once_with(
mock.sentinel.context,
fake_firewall['id'],
'ACTIVE')
def test_update_firewall_with_no_rtrs_and_no_rtrs_added_nor_deleted(self):
fake_firewall = {'id': 0, 'tenant_id': 1,
'admin_state_up': True,
'add-router-ids': [],
'del-router-ids': [],
'router_ids': []}
self.api.plugin_rpc = mock.Mock()
with mock.patch.object(self.api.fwaas_driver, 'update_firewall'
) as mock_driver_update_firewall, \
mock.patch.object(self.api.fwplugin_rpc, 'set_firewall_status'
) as mock_set_firewall_status:
mock_driver_update_firewall.return_value = True
self.api.update_firewall(
context=mock.sentinel.context,
firewall=fake_firewall, host='host')
mock_set_firewall_status.assert_called_once_with(
mock.sentinel.context,
fake_firewall['id'],
'INACTIVE')
def test_delete_firewall(self):
fake_firewall = {'id': 0, 'tenant_id': 1,
'admin_state_up': True,
'add-router-ids': [],
'del-router-ids': [3, 4],
'last-router': True}
self.api.plugin_rpc = mock.Mock()
with mock.patch.object(self.api, '_get_router_info_list_for_tenant'
) as mock_get_router_info_list_for_tenant, \
mock.patch.object(self.api.fwaas_driver, 'delete_firewall'
) as mock_driver_delete_firewall, \
mock.patch.object(self.api.fwplugin_rpc, 'firewall_deleted'
) as mock_firewall_deleted:
mock_driver_delete_firewall.return_value = True
self.api.delete_firewall(
context=mock.sentinel.context,
firewall=fake_firewall, host='host')
mock_get_router_info_list_for_tenant.assert_called_once_with(
fake_firewall['del-router-ids'], fake_firewall['tenant_id'])
mock_firewall_deleted.assert_called_once_with(
mock.sentinel.context,
fake_firewall['id'])
def _prepare_router_data(self):
return router_info.RouterInfo(self.router_id,
**self.ri_kwargs)
def test_get_router_info_list_for_tenant(self):
ri = self._prepare_router_data()
routers = [ri.router]
router_ids = [router['id'] for router in routers]
self.api.router_info = {ri.router_id: ri}
with mock.patch.object(ip_lib.IPWrapper,
'get_namespaces') as mock_get_namespaces:
mock_get_namespaces.return_value = []
router_info_list = self.api._get_router_info_list_for_tenant(
router_ids,
ri.router['tenant_id'])
mock_get_namespaces.assert_called_once_with()
self.assertFalse(router_info_list)
def _get_router_info_list_router_without_router_info_helper(self,
rtr_with_ri):
# ri.router with associated router_info (ri)
# rtr2 has no router_info
ri = self._prepare_router_data()
rtr2 = {'id': str(uuid.uuid4()), 'tenant_id': ri.router['tenant_id']}
routers = [rtr2]
self.api.router_info = {}
ri_expected = []
if rtr_with_ri:
self.api.router_info[ri.router_id] = ri
routers.append(ri.router)
ri_expected.append(ri)
router_ids = [router['id'] for router in routers]
with mock.patch.object(ip_lib.IPWrapper,
'get_namespaces') as mock_get_namespaces:
mock_get_namespaces.return_value = ri.ns_name
router_info_list = self.api._get_router_info_list_for_tenant(
router_ids,
ri.router['tenant_id'])
self.assertEqual(ri_expected, router_info_list)
def test_get_router_info_list_router_without_router_info(self):
self._get_router_info_list_router_without_router_info_helper(
rtr_with_ri=False)
def test_get_router_info_list_two_routers_one_without_router_info(self):
self._get_router_info_list_router_without_router_info_helper(
rtr_with_ri=True)
neutron-fwaas-8.0.0/neutron_fwaas/tests/unit/services/firewall/agents/l3reference/__init__.py 0000664 0005670 0005671 00000000000 12701407720 033652 0 ustar jenkins jenkins 0000000 0000000 neutron-fwaas-8.0.0/neutron_fwaas/tests/unit/services/firewall/agents/varmour/ 0000775 0005670 0005671 00000000000 12701410073 031044 5 ustar jenkins jenkins 0000000 0000000 neutron-fwaas-8.0.0/neutron_fwaas/tests/unit/services/firewall/agents/varmour/__init__.py 0000664 0005670 0005671 00000000000 12701407720 033150 0 ustar jenkins jenkins 0000000 0000000 neutron-fwaas-8.0.0/neutron_fwaas/tests/unit/services/firewall/agents/varmour/test_varmour_router.py0000664 0005670 0005671 00000020242 12701407720 035555 0 ustar jenkins jenkins 0000000 0000000 # Copyright 2013 vArmour Networks Inc.
# All Rights Reserved.
#
# 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.
import mock
from neutron.agent.common import config as agent_config
from neutron.agent.l3 import config as l3_config
from neutron.agent.l3 import ha
from neutron.agent.l3 import router_info
from neutron.agent.linux import interface
from neutron.common import config as base_config
from neutron_fwaas.services.firewall.agents.varmour import varmour_router
from neutron_fwaas.tests import base
from neutron_lib import constants as l3_constants
from oslo_utils import uuidutils
_uuid = uuidutils.generate_uuid
HOSTNAME = 'myhost'
FAKE_DIRECTOR = '1.1.1.1'
class TestVarmourRouter(base.BaseTestCase):
def setUp(self):
super(TestVarmourRouter, self).setUp()
self.conf = agent_config.setup_conf()
self.conf.register_opts(base_config.core_opts)
self.conf.register_opts(l3_config.OPTS)
self.conf.register_opts(ha.OPTS)
agent_config.register_process_monitor_opts(self.conf)
agent_config.register_interface_driver_opts_helper(self.conf)
self.conf.register_opts(interface.OPTS)
self.conf.set_override('interface_driver',
'neutron.agent.linux.interface.NullDriver')
self.conf.state_path = ''
self.device_exists_p = mock.patch(
'neutron.agent.linux.ip_lib.device_exists')
self.device_exists = self.device_exists_p.start()
self.utils_exec_p = mock.patch(
'neutron.agent.linux.utils.execute')
self.utils_exec = self.utils_exec_p.start()
self.external_process_p = mock.patch(
'neutron.agent.linux.external_process.ProcessManager')
self.external_process = self.external_process_p.start()
self.makedirs_p = mock.patch('os.makedirs')
self.makedirs = self.makedirs_p.start()
self.dvr_cls_p = mock.patch('neutron.agent.linux.interface.NullDriver')
driver_cls = self.dvr_cls_p.start()
self.mock_driver = mock.MagicMock()
self.mock_driver.DEV_NAME_LEN = (
interface.LinuxInterfaceDriver.DEV_NAME_LEN)
driver_cls.return_value = self.mock_driver
self.ip_cls_p = mock.patch('neutron.agent.linux.ip_lib.IPWrapper')
ip_cls = self.ip_cls_p.start()
self.mock_ip = mock.MagicMock()
ip_cls.return_value = self.mock_ip
mock.patch('neutron.agent.l3.agent.L3PluginApi').start()
self.looping_call_p = mock.patch(
'oslo_service.loopingcall.FixedIntervalLoopingCall')
self.looping_call_p.start()
self.ri_kwargs = {'agent_conf': self.conf,
'interface_driver': self.mock_driver}
def _create_router(self):
router = varmour_router.vArmourL3NATAgent(HOSTNAME, self.conf)
router.rest.server = FAKE_DIRECTOR
router.rest.user = 'varmour'
router.rest.passwd = 'varmour'
return router
def _del_all_internal_ports(self, router):
router[l3_constants.INTERFACE_KEY] = []
def _del_internal_ports(self, router, port_idx):
del router[l3_constants.INTERFACE_KEY][port_idx]
def _add_internal_ports(self, router, port_count=1):
self._del_all_internal_ports(router)
for i in range(port_count):
port = {'id': _uuid(),
'network_id': _uuid(),
'admin_state_up': True,
'fixed_ips': [{'ip_address': '10.0.%s.4' % i,
'subnet_id': _uuid()}],
'mac_address': 'ca:fe:de:ad:be:ef',
'subnet': {'cidr': '10.0.%s.0/24' % i,
'gateway_ip': '10.0.%s.1' % i}}
router[l3_constants.INTERFACE_KEY].append(port)
def _del_all_floating_ips(self, router):
router[l3_constants.FLOATINGIP_KEY] = []
def _del_floating_ips(self, router, port_idx):
del router[l3_constants.FLOATINGIP_KEY][port_idx]
def _add_floating_ips(self, router, port_count=1):
self._del_all_floating_ips(router)
for i in range(port_count):
fip = {'id': _uuid(),
'port_id': router['gw_port']['id'],
'floating_ip_address': '172.24.4.%s' % (100 + i),
'fixed_ip_address': '10.0.0.%s' % (100 + i)}
router[l3_constants.FLOATINGIP_KEY].append(fip)
def _prepare_router_data(self, enable_snat=None):
router_id = _uuid()
ex_gw_port = {'id': _uuid(),
'mac_address': 'ca:fe:de:ad:be:ee',
'network_id': _uuid(),
'fixed_ips': [{'ip_address': '172.24.4.2',
'subnet_id': _uuid()}],
'subnet': {'cidr': '172.24.4.0/24',
'gateway_ip': '172.24.4.1'},
'ip_cidr': '172.24.4.226/28'}
int_ports = []
router = {
'id': router_id,
'distributed': False,
l3_constants.INTERFACE_KEY: int_ports,
'routes': [],
'gw_port': ex_gw_port}
if enable_snat is not None:
router['enable_snat'] = enable_snat
ri = router_info.RouterInfo(router_id=router['id'], router=router,
**self.ri_kwargs)
return ri
def test_agent_add_internal_network(self):
router = self._create_router()
self._add_internal_ports = mock.Mock()
ri = self._prepare_router_data(enable_snat=True)
router._router_added(ri.router['id'], ri.router)
self._add_internal_ports(ri.router, port_count=1)
self._add_internal_ports.assert_called_once_with(ri.router,
port_count=1)
def test_agent_remove_internal_network(self):
router = self._create_router()
self._del_internal_ports = mock.Mock()
ri = self._prepare_router_data(enable_snat=True)
router._router_added(ri.router['id'], ri.router)
self._add_internal_ports(ri.router, port_count=2)
self._del_internal_ports(ri.router, 0)
self._del_internal_ports.assert_called_once_with(ri.router, 0)
def test_agent_add_floating_ips(self):
router = self._create_router()
self._add_floating_ips = mock.Mock()
ri = self._prepare_router_data(enable_snat=True)
self._add_internal_ports(ri.router, port_count=1)
router._router_added(ri.router['id'], ri.router)
self._add_floating_ips(ri.router, port_count=1)
self._add_floating_ips.assert_called_once_with(ri.router, port_count=1)
def test_agent_remove_floating_ips(self):
router = self._create_router()
self._del_floating_ips = mock.Mock()
ri = self._prepare_router_data(enable_snat=True)
self._add_internal_ports(ri.router, port_count=1)
self._add_floating_ips(ri.router, port_count=2)
router._router_added(ri.router['id'], ri.router)
self._del_floating_ips(ri.router, 0)
self._del_floating_ips.assert_called_once_with(ri.router, 0)
def test_agent_external_gateway(self):
router = self._create_router()
router._router_removed = mock.Mock()
ri = self._prepare_router_data(enable_snat=True)
router._router_added(ri.router['id'], ri.router)
router._router_removed(ri.router['id'])
router._router_removed.assert_called_once_with(ri.router['id'])
def test_agent_snat_enable(self):
router = self._create_router()
ri = self._prepare_router_data(enable_snat=True)
router._router_added(ri.router['id'], ri.router)
ri.router['enable_snat'] = False
self.assertFalse(ri.router['enable_snat'])
neutron-fwaas-8.0.0/neutron_fwaas/tests/unit/services/firewall/agents/__init__.py 0000664 0005670 0005671 00000000000 12701407720 031455 0 ustar jenkins jenkins 0000000 0000000 neutron-fwaas-8.0.0/neutron_fwaas/tests/unit/services/firewall/agents/test_firewall_service.py 0000664 0005670 0005671 00000004556 12701407720 034326 0 ustar jenkins jenkins 0000000 0000000 # Copyright 2014 OpenStack Foundation.
# All Rights Reserved.
#
# 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.
from neutron.tests import base
from oslo_config import cfg
from neutron_fwaas.services.firewall.agents import firewall_service
FWAAS_NOP_DEVICE = ('neutron_fwaas.tests.unit.services.firewall.agents.'
'test_firewall_agent_api.NoopFwaasDriver')
class TestFirewallDeviceDriverLoading(base.BaseTestCase):
def setUp(self):
super(TestFirewallDeviceDriverLoading, self).setUp()
self.service = firewall_service.FirewallService()
def test_loading_firewall_device_driver(self):
"""Get the sole device driver for FWaaS."""
cfg.CONF.set_override('driver',
FWAAS_NOP_DEVICE,
'fwaas')
driver = self.service.load_device_drivers()
self.assertIsNotNone(driver)
self.assertIn(driver.__class__.__name__, FWAAS_NOP_DEVICE)
def test_fail_no_such_firewall_device_driver(self):
"""Failure test of import error for FWaaS device driver."""
cfg.CONF.set_override('driver',
'no.such.class',
'fwaas')
self.assertRaises(ImportError,
self.service.load_device_drivers)
def test_fail_firewall_no_device_driver_specified(self):
"""Failure test when no FWaaS device driver is specified.
This is a configuration error, as the user must specify a device
driver, when enabling the firewall service (and there is no default
configuration set. We'll simulate that by using an empty string.
"""
cfg.CONF.set_override('driver',
'',
'fwaas')
self.assertRaises(ValueError,
self.service.load_device_drivers)
neutron-fwaas-8.0.0/neutron_fwaas/tests/unit/services/firewall/agents/vyatta/ 0000775 0005670 0005671 00000000000 12701410073 030661 5 ustar jenkins jenkins 0000000 0000000 neutron-fwaas-8.0.0/neutron_fwaas/tests/unit/services/firewall/agents/vyatta/test_vyatta_utils.py 0000664 0005670 0005671 00000007751 12701407720 035041 0 ustar jenkins jenkins 0000000 0000000 # Copyright 2015 OpenStack Foundation.
# All Rights Reserved.
#
# 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.
import sys
import mock
from neutron.tests import base
from neutron_lib import constants as l3_constants
from six.moves.urllib import parse
# Mocking imports of 3rd party vyatta library in unit tests and all modules
# that depends on this library. Import will fail if not mocked and 3rd party
# vyatta library is not installed.
with mock.patch.dict(sys.modules, {
'networking_brocade': mock.Mock(),
'networking_brocade.vyatta': mock.Mock(),
'networking_brocade.vyatta.vrouter': mock.Mock(),
}):
from networking_brocade.vyatta.vrouter import client as vyatta_client
from neutron_fwaas.services.firewall.agents.vyatta import vyatta_utils
def fake_cmd(*args, **kwargs):
return (args, kwargs)
class TestVyattaUtils(base.BaseTestCase):
def setUp(self):
super(TestVyattaUtils, self).setUp()
mock.patch.object(vyatta_client, 'SetCmd', fake_cmd).start()
mock.patch.object(vyatta_client, 'DeleteCmd', fake_cmd).start()
def test_get_firewall_name(self):
fake_firewall = {
'id': '74bc106d-fff0-4f92-ac1a-60d4b6b44fe1',
}
fw_name = vyatta_utils.get_firewall_name(
None, fake_firewall)
self.assertEqual('74bc106dfff04f92ac1a60d4b6b4', fw_name)
def test_get_trusted_zone_name(self):
fake_apply_list = object()
self.assertEqual(
'Internal_Trust', vyatta_utils.get_trusted_zone_name(
fake_apply_list))
def test_get_untrusted_zone_name(self):
fake_apply_list = object()
self.assertEqual(
'External_Untrust', vyatta_utils.get_untrusted_zone_name(
fake_apply_list))
def test_get_zone_cmds(self):
firewall_name = 'fake_firewall0'
eth_iface = 'eth0'
fake_api = mock.NonCallableMock()
fake_api.get_ethernet_if_id.return_value = eth_iface
mac_address = '00:00:00:00:00:00'
fake_apply_rule = mock.NonCallableMock()
fake_apply_rule.router = {
'gw_port': {
'mac_address': mac_address},
l3_constants.INTERFACE_KEY: [{
'mac_address': mac_address}]
}
trusted_zone_name = vyatta_utils.get_trusted_zone_name(
fake_apply_rule)
untrusted_zone_name = vyatta_utils.get_untrusted_zone_name(
fake_apply_rule)
cmds_actual = vyatta_utils.get_zone_cmds(
fake_api, fake_apply_rule, firewall_name)
cmds_expect = [
vyatta_client.DeleteCmd('zone-policy'),
vyatta_client.SetCmd(
vyatta_utils.ZONE_INTERFACE_CMD.format(
trusted_zone_name, eth_iface)),
vyatta_client.SetCmd(
vyatta_utils.ZONE_INTERFACE_CMD.format(
untrusted_zone_name, eth_iface)),
vyatta_client.SetCmd(
vyatta_utils.ZONE_FIREWALL_CMD.format(
trusted_zone_name, untrusted_zone_name,
parse.quote_plus(firewall_name))),
vyatta_client.SetCmd(
vyatta_utils.ZONE_FIREWALL_CMD.format(
untrusted_zone_name, trusted_zone_name,
parse.quote_plus(firewall_name))),
]
self.assertEqual(cmds_expect, cmds_actual)
fake_api.get_ethernet_if_id.assert_has_calls([
mock.call(mac_address),
mock.call(mac_address),
])
neutron-fwaas-8.0.0/neutron_fwaas/tests/unit/services/firewall/agents/vyatta/__init__.py 0000664 0005670 0005671 00000000000 12701407720 032765 0 ustar jenkins jenkins 0000000 0000000 ././@LongLink 0000000 0000000 0000000 00000000146 00000000000 011216 L ustar 0000000 0000000 neutron-fwaas-8.0.0/neutron_fwaas/tests/unit/services/firewall/agents/vyatta/test_firewall_service.py neutron-fwaas-8.0.0/neutron_fwaas/tests/unit/services/firewall/agents/vyatta/test_firewall_service.p0000664 0005670 0005671 00000006446 12701407720 035445 0 ustar jenkins jenkins 0000000 0000000 # Copyright 2015 OpenStack Foundation.
# All Rights Reserved.
#
# 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.
import sys
import uuid
import mock
from neutron.tests import base
class FakeL3AgentMidleware(object):
def __init__(self, host, conf=None):
self._vyatta_clients_pool = mock.Mock()
self.fwplugin_rpc = mock.Mock()
self.conf = conf
# Mocking imports of 3rd party vyatta library in unit tests and all modules
# that depends on this library. Import will fail if not mocked and 3rd party
# vyatta library is not installed.
with mock.patch.dict(sys.modules, {
'networking_brocade': mock.Mock(),
'networking_brocade.vyatta': mock.Mock(),
'networking_brocade.vyatta.common': mock.Mock(),
'networking_brocade.vyatta.vrouter': mock.Mock(),
}):
from networking_brocade.vyatta.common import l3_agent
l3_agent.L3AgentMiddleware = FakeL3AgentMidleware
from neutron_fwaas.services.firewall.agents.vyatta import firewall_service
from neutron_fwaas.services.firewall.agents.vyatta import fwaas_agent
from neutron_fwaas.services.firewall.agents.vyatta import vyatta_utils
def fake_cmd(*args, **kwargs):
return (args, kwargs)
class TestVyattaFirewallService(base.BaseTestCase):
def test_sync_firewall_zones(self):
agent = self._make_agent()
fake_client = mock.Mock()
agent._vyatta_clients_pool.get_by_db_lookup.return_value = fake_client
router_id = str(uuid.uuid4())
fake_fw_record = {
'id': str(uuid.uuid4()),
'name': 'fake-fw-record0',
'router_ids': [router_id]
}
agent.fwplugin_rpc.get_firewalls_for_tenant.return_value = [
fake_fw_record
]
router = {
'id': router_id,
'tenant_id': str(uuid.uuid4())
}
router_info = mock.NonCallableMock()
router_info.router = router
cmd_list = [
fake_cmd("zone-policy"),
fake_cmd(vyatta_utils.ZONE_INTERFACE_CMD.format(
'fake-zone', 'eth0')),
fake_cmd(vyatta_utils.ZONE_FIREWALL_CMD.format(
vyatta_utils.UNTRUST_ZONE, vyatta_utils.TRUST_ZONE,
'fake-fw-name'))
]
with mock.patch.object(
vyatta_utils, 'get_zone_cmds') as get_zone_mock:
get_zone_mock.return_value = cmd_list
firewall_service.sync_firewall_zones(
None, None, agent, router=router_info)
agent._vyatta_clients_pool.get_by_db_lookup.assert_called_once_with(
router_info.router['id'], mock.ANY)
fake_client.exec_cmd_batch.assert_called_once_with(cmd_list)
def _make_agent(self):
agent = fwaas_agent.VyattaFirewallAgent('fake-host')
agent.router_info = dict()
return agent
neutron-fwaas-8.0.0/neutron_fwaas/tests/unit/services/firewall/test_fwaas_plugin.py 0000664 0005670 0005671 00000077205 12701407720 032200 0 ustar jenkins jenkins 0000000 0000000 # Copyright 2013 Big Switch Networks, Inc.
# All Rights Reserved.
#
# 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.
import mock
from neutron.api.v2 import attributes as attr
from neutron import context
from neutron import manager
from neutron.plugins.common import constants as const
from neutron.tests import fake_notifier
from neutron.tests.unit.extensions import test_l3 as test_l3_plugin
from oslo_config import cfg
import six
from webob import exc
import neutron_fwaas.extensions
from neutron_fwaas.extensions import firewall
from neutron_fwaas.extensions import firewallrouterinsertion
from neutron_fwaas.services.firewall import fwaas_plugin
from neutron_fwaas.tests import base
from neutron_fwaas.tests.unit.db.firewall import (
test_firewall_db as test_db_firewall)
extensions_path = neutron_fwaas.extensions.__path__[0]
FW_PLUGIN_KLASS = (
"neutron_fwaas.services.firewall.fwaas_plugin.FirewallPlugin"
)
class FirewallTestExtensionManager(test_l3_plugin.L3TestExtensionManager):
def get_resources(self):
res = super(FirewallTestExtensionManager, self).get_resources()
firewall.RESOURCE_ATTRIBUTE_MAP['firewalls'].update(
firewallrouterinsertion.EXTENDED_ATTRIBUTES_2_0['firewalls'])
return res + firewall.Firewall.get_resources()
def get_actions(self):
return []
def get_request_extensions(self):
return []
class TestFirewallRouterInsertionBase(
test_db_firewall.FirewallPluginDbTestCase):
def setUp(self, core_plugin=None, fw_plugin=None, ext_mgr=None):
self.agentapi_del_fw_p = mock.patch(test_db_firewall.DELETEFW_PATH,
create=True, new=test_db_firewall.FakeAgentApi().delete_firewall)
self.agentapi_del_fw_p.start()
# the plugin without L3 support
plugin = 'neutron.tests.unit.extensions.test_l3.TestNoL3NatPlugin'
# the L3 service plugin
l3_plugin = ('neutron.tests.unit.extensions.test_l3.'
'TestL3NatServicePlugin')
cfg.CONF.set_override('api_extensions_path', extensions_path)
self.saved_attr_map = {}
for resource, attrs in six.iteritems(attr.RESOURCE_ATTRIBUTE_MAP):
self.saved_attr_map[resource] = attrs.copy()
if not fw_plugin:
fw_plugin = FW_PLUGIN_KLASS
service_plugins = {'l3_plugin_name': l3_plugin,
'fw_plugin_name': fw_plugin}
if not ext_mgr:
ext_mgr = FirewallTestExtensionManager()
super(test_db_firewall.FirewallPluginDbTestCase, self).setUp(
plugin=plugin, service_plugins=service_plugins, ext_mgr=ext_mgr)
self.setup_notification_driver()
self.l3_plugin = manager.NeutronManager.get_service_plugins().get(
const.L3_ROUTER_NAT)
self.plugin = manager.NeutronManager.get_service_plugins().get(
const.FIREWALL)
self.callbacks = self.plugin.endpoints[0]
def restore_attribute_map(self):
# Remove the csrfirewallinsertion extension
firewall.RESOURCE_ATTRIBUTE_MAP['firewalls'].pop('router_ids')
# Restore the original RESOURCE_ATTRIBUTE_MAP
attr.RESOURCE_ATTRIBUTE_MAP = self.saved_attr_map
def tearDown(self):
self.restore_attribute_map()
super(TestFirewallRouterInsertionBase, self).tearDown()
def _create_firewall(self, fmt, name, description, firewall_policy_id=None,
admin_state_up=True, expected_res_status=None,
**kwargs):
tenant_id = kwargs.get('tenant_id', self._tenant_id)
router_ids = kwargs.get('router_ids')
if firewall_policy_id is None:
res = self._create_firewall_policy(fmt, 'fwp',
description="firewall_policy",
shared=True,
firewall_rules=[],
audited=True)
firewall_policy = self.deserialize(fmt or self.fmt, res)
firewall_policy_id = firewall_policy["firewall_policy"]["id"]
data = {'firewall': {'name': name,
'description': description,
'firewall_policy_id': firewall_policy_id,
'admin_state_up': admin_state_up,
'tenant_id': tenant_id}}
if router_ids is not None:
data['firewall']['router_ids'] = router_ids
firewall_req = self.new_create_request('firewalls', data, fmt)
firewall_res = firewall_req.get_response(self.ext_api)
if expected_res_status:
self.assertEqual(expected_res_status, firewall_res.status_int)
return firewall_res
class TestFirewallCallbacks(TestFirewallRouterInsertionBase):
def setUp(self):
super(TestFirewallCallbacks,
self).setUp(fw_plugin=FW_PLUGIN_KLASS)
self.callbacks = self.plugin.endpoints[0]
def test_set_firewall_status(self):
ctx = context.get_admin_context()
with self.firewall_policy() as fwp:
fwp_id = fwp['firewall_policy']['id']
with self.firewall(
firewall_policy_id=fwp_id,
admin_state_up=test_db_firewall.ADMIN_STATE_UP
) as fw:
fw_id = fw['firewall']['id']
res = self.callbacks.set_firewall_status(ctx, fw_id,
const.ACTIVE,
host='dummy')
fw_db = self.plugin.get_firewall(ctx, fw_id)
self.assertEqual(const.ACTIVE, fw_db['status'])
self.assertTrue(res)
res = self.callbacks.set_firewall_status(ctx, fw_id,
const.ERROR)
fw_db = self.plugin.get_firewall(ctx, fw_id)
self.assertEqual(const.ERROR, fw_db['status'])
self.assertFalse(res)
def test_set_firewall_status_pending_delete(self):
ctx = context.get_admin_context()
with self.firewall_policy() as fwp:
fwp_id = fwp['firewall_policy']['id']
with self.firewall(
firewall_policy_id=fwp_id,
admin_state_up=test_db_firewall.ADMIN_STATE_UP
) as fw:
fw_id = fw['firewall']['id']
fw_db = self.plugin._get_firewall(ctx, fw_id)
fw_db['status'] = const.PENDING_DELETE
ctx.session.flush()
res = self.callbacks.set_firewall_status(ctx, fw_id,
const.ACTIVE,
host='dummy')
fw_db = self.plugin.get_firewall(ctx, fw_id)
self.assertEqual(const.PENDING_DELETE, fw_db['status'])
self.assertFalse(res)
def test_firewall_deleted(self):
ctx = context.get_admin_context()
with self.firewall_policy() as fwp:
fwp_id = fwp['firewall_policy']['id']
with self.firewall(firewall_policy_id=fwp_id,
admin_state_up=test_db_firewall.ADMIN_STATE_UP,
do_delete=False) as fw:
fw_id = fw['firewall']['id']
with ctx.session.begin(subtransactions=True):
fw_db = self.plugin._get_firewall(ctx, fw_id)
fw_db['status'] = const.PENDING_DELETE
ctx.session.flush()
res = self.callbacks.firewall_deleted(ctx, fw_id,
host='dummy')
self.assertTrue(res)
self.assertRaises(firewall.FirewallNotFound,
self.plugin.get_firewall,
ctx, fw_id)
def test_firewall_deleted_error(self):
ctx = context.get_admin_context()
with self.firewall_policy() as fwp:
fwp_id = fwp['firewall_policy']['id']
with self.firewall(
firewall_policy_id=fwp_id,
admin_state_up=test_db_firewall.ADMIN_STATE_UP,
) as fw:
fw_id = fw['firewall']['id']
res = self.callbacks.firewall_deleted(ctx, fw_id,
host='dummy')
self.assertFalse(res)
fw_db = self.plugin._get_firewall(ctx, fw_id)
self.assertEqual(const.ERROR, fw_db['status'])
def test_get_firewall_for_tenant(self):
tenant_id = 'test-tenant'
ctx = context.Context('', tenant_id)
with self.firewall_rule(name='fwr1', tenant_id=tenant_id) as fwr1, \
self.firewall_rule(name='fwr2', tenant_id=tenant_id) as fwr2, \
self.firewall_rule(name='fwr3', tenant_id=tenant_id) as fwr3:
with self.firewall_policy(tenant_id=tenant_id) as fwp:
fwp_id = fwp['firewall_policy']['id']
fr = [fwr1, fwr2, fwr3]
fw_rule_ids = [r['firewall_rule']['id'] for r in fr]
data = {'firewall_policy':
{'firewall_rules': fw_rule_ids}}
req = self.new_update_request('firewall_policies', data,
fwp_id)
res = req.get_response(self.ext_api)
attrs = self._get_test_firewall_attrs()
attrs['firewall_policy_id'] = fwp_id
with self.firewall(
firewall_policy_id=fwp_id,
tenant_id=tenant_id,
admin_state_up=test_db_firewall.ADMIN_STATE_UP) as fw:
fw_id = fw['firewall']['id']
res = self.callbacks.get_firewalls_for_tenant(ctx,
host='dummy')
fw_rules = (
self.plugin._make_firewall_dict_with_rules(ctx,
fw_id)
)
fw_rules['add-router-ids'] = []
fw_rules['del-router-ids'] = []
self.assertEqual(fw_rules, res[0])
self._compare_firewall_rule_lists(
fwp_id, fr, res[0]['firewall_rule_list'])
def test_get_firewall_for_tenant_without_rules(self):
tenant_id = 'test-tenant'
ctx = context.Context('', tenant_id)
with self.firewall_policy(tenant_id=tenant_id) as fwp:
fwp_id = fwp['firewall_policy']['id']
attrs = self._get_test_firewall_attrs()
attrs['firewall_policy_id'] = fwp_id
with self.firewall(firewall_policy_id=fwp_id, tenant_id=tenant_id,
admin_state_up=test_db_firewall.ADMIN_STATE_UP
) as fw:
# router_ids is not present in the firewall db
# but is added in the get_firewalls override by plugin
fw_list = [fw['firewall']]
f = self.callbacks.get_firewalls_for_tenant_without_rules
res = f(ctx, host='dummy')
for fw in res:
del fw['shared']
self.assertEqual(fw_list, res)
class TestFirewallAgentApi(base.BaseTestCase):
def setUp(self):
super(TestFirewallAgentApi, self).setUp()
self.api = fwaas_plugin.FirewallAgentApi('topic', 'host')
def test_init(self):
self.assertEqual('topic', self.api.client.target.topic)
self.assertEqual('host', self.api.host)
def _call_test_helper(self, method_name):
with mock.patch.object(self.api.client, 'cast') as rpc_mock, \
mock.patch.object(self.api.client, 'prepare') as prepare_mock:
prepare_mock.return_value = self.api.client
getattr(self.api, method_name)(mock.sentinel.context, 'test')
prepare_args = {'fanout': True}
prepare_mock.assert_called_once_with(**prepare_args)
rpc_mock.assert_called_once_with(mock.sentinel.context, method_name,
firewall='test', host='host')
def test_create_firewall(self):
self._call_test_helper('create_firewall')
def test_update_firewall(self):
self._call_test_helper('update_firewall')
def test_delete_firewall(self):
self._call_test_helper('delete_firewall')
class TestFirewallPluginBase(TestFirewallRouterInsertionBase,
test_l3_plugin.L3NatTestCaseMixin):
def setUp(self):
super(TestFirewallPluginBase, self).setUp(fw_plugin=FW_PLUGIN_KLASS)
fake_notifier.reset()
def tearDown(self):
super(TestFirewallPluginBase, self).tearDown()
def test_create_firewall_routers_not_specified(self):
"""neutron firewall-create test-policy """
with self.router(name='router1', admin_state_up=True,
tenant_id=self._tenant_id):
with self.router(name='router2', admin_state_up=True,
tenant_id=self._tenant_id):
with self.firewall() as fw1:
self.assertEqual(const.PENDING_CREATE,
fw1['firewall']['status'])
def test_create_firewall_routers_specified(self):
"""neutron firewall-create test-policy --router-ids "r1 r2" """
with self.router(name='router1', admin_state_up=True,
tenant_id=self._tenant_id) as router1:
with self.router(name='router2', admin_state_up=True,
tenant_id=self._tenant_id) as router2:
router_ids = [router1['router']['id'], router2['router']['id']]
with self.firewall(router_ids=router_ids) as fw1:
self.assertEqual(const.PENDING_CREATE,
fw1['firewall']['status'])
def test_create_firewall_routers_present_empty_list_specified(self):
"""neutron firewall-create test-policy --router-ids "" """
with self.router(name='router1', admin_state_up=True,
tenant_id=self._tenant_id):
with self.router(name='router2', admin_state_up=True,
tenant_id=self._tenant_id):
router_ids = []
with self.firewall(router_ids=router_ids) as fw1:
self.assertEqual(const.INACTIVE,
fw1['firewall']['status'])
def test_create_firewall_no_routers_empty_list_specified(self):
"""neutron firewall-create test-policy --router-ids "" """
router_ids = []
with self.firewall(router_ids=router_ids) as fw1:
self.assertEqual(const.INACTIVE,
fw1['firewall']['status'])
def test_create_second_firewall_on_same_tenant(self):
"""fw1 created with default routers, fw2 no routers on same tenant."""
with self.router(name='router1', admin_state_up=True,
tenant_id=self._tenant_id):
with self.router(name='router2', admin_state_up=True,
tenant_id=self._tenant_id):
router_ids = []
with self.firewall() as fw1:
with self.firewall(router_ids=router_ids) as fw2:
self.assertEqual(const.PENDING_CREATE,
fw1['firewall']['status'])
self.assertEqual(const.INACTIVE,
fw2['firewall']['status'])
def test_create_firewall_admin_not_affected_by_other_tenant(self):
# Create fw with admin after creating fw with other tenant
with self.firewall(tenant_id='other-tenant') as fw1:
with self.firewall() as fw2:
self.assertEqual('other-tenant', fw1['firewall']['tenant_id'])
self.assertEqual(self._tenant_id, fw2['firewall']['tenant_id'])
def test_update_firewall(self):
ctx = context.get_admin_context()
name = "new_firewall1"
attrs = self._get_test_firewall_attrs(name)
with self.router(name='router1', admin_state_up=True,
tenant_id=self._tenant_id) as router1:
with self.firewall_policy() as fwp:
fwp_id = fwp['firewall_policy']['id']
attrs['firewall_policy_id'] = fwp_id
with self.firewall(
firewall_policy_id=fwp_id,
admin_state_up=test_db_firewall.ADMIN_STATE_UP,
router_ids=[router1['router']['id']]
) as firewall:
fw_id = firewall['firewall']['id']
res = self.callbacks.set_firewall_status(ctx, fw_id,
const.ACTIVE)
data = {'firewall': {'name': name}}
req = self.new_update_request('firewalls', data, fw_id)
res = self.deserialize(self.fmt,
req.get_response(self.ext_api))
attrs = self._replace_firewall_status(attrs,
const.PENDING_CREATE,
const.PENDING_UPDATE)
for k, v in six.iteritems(attrs):
self.assertEqual(v, res['firewall'][k])
def test_update_firewall_fails_when_firewall_pending(self):
name = "new_firewall1"
attrs = self._get_test_firewall_attrs(name)
with self.router(name='router1', admin_state_up=True,
tenant_id=self._tenant_id) as router1:
with self.firewall_policy() as fwp:
fwp_id = fwp['firewall_policy']['id']
attrs['firewall_policy_id'] = fwp_id
with self.firewall(
firewall_policy_id=fwp_id,
admin_state_up=test_db_firewall.ADMIN_STATE_UP,
router_ids=[router1['router']['id']]
) as firewall:
fw_id = firewall['firewall']['id']
data = {'firewall': {'name': name}}
req = self.new_update_request('firewalls', data, fw_id)
res = req.get_response(self.ext_api)
self.assertEqual(exc.HTTPConflict.code, res.status_int)
def test_update_firewall_with_router_when_firewall_inactive(self):
name = "firewall1"
attrs = self._get_test_firewall_attrs(name)
with self.router(name='router1', admin_state_up=True,
tenant_id=self._tenant_id) as router1:
with self.firewall_policy() as fwp:
fwp_id = fwp['firewall_policy']['id']
attrs['firewall_policy_id'] = fwp_id
with self.firewall(
name=name,
firewall_policy_id=fwp_id,
admin_state_up=test_db_firewall.ADMIN_STATE_UP,
router_ids=[]
) as firewall:
fw_id = firewall['firewall']['id']
data = {
'firewall': {'router_ids': [router1['router']['id']]}}
req = self.new_update_request('firewalls', data, fw_id)
res = self.deserialize(self.fmt,
req.get_response(self.ext_api))
attrs = self._replace_firewall_status(attrs,
const.PENDING_CREATE,
const.PENDING_UPDATE)
for k, v in six.iteritems(attrs):
self.assertEqual(v, res['firewall'][k])
def test_update_firewall_shared_fails_for_non_admin(self):
ctx = context.get_admin_context()
with self.router(name='router1', admin_state_up=True,
tenant_id=self._tenant_id) as router1:
with self.firewall_policy() as fwp:
fwp_id = fwp['firewall_policy']['id']
with self.firewall(
firewall_policy_id=fwp_id,
admin_state_up=test_db_firewall.ADMIN_STATE_UP,
tenant_id='noadmin',
router_ids=[router1['router']['id']]
) as firewall:
fw_id = firewall['firewall']['id']
self.callbacks.set_firewall_status(ctx, fw_id,
const.ACTIVE)
data = {'firewall': {'shared': True}}
req = self.new_update_request(
'firewalls', data, fw_id,
context=context.Context('', 'noadmin'))
res = req.get_response(self.ext_api)
self.assertEqual(exc.HTTPForbidden.code, res.status_int)
def test_update_firewall_policy_fails_when_firewall_pending(self):
name = "new_firewall1"
attrs = self._get_test_firewall_attrs(name)
with self.router(name='router1', admin_state_up=True,
tenant_id=self._tenant_id):
with self.firewall_policy() as fwp:
fwp_id = fwp['firewall_policy']['id']
attrs['firewall_policy_id'] = fwp_id
with self.firewall(
firewall_policy_id=fwp_id,
admin_state_up=test_db_firewall.ADMIN_STATE_UP
):
data = {'firewall_policy': {'name': name}}
req = self.new_update_request('firewall_policies',
data, fwp_id)
res = req.get_response(self.ext_api)
self.assertEqual(exc.HTTPConflict.code, res.status_int)
def test_update_firewall_rule_fails_when_firewall_pending(self):
with self.router(name='router1', admin_state_up=True,
tenant_id=self._tenant_id):
with self.firewall_rule(name='fwr1') as fr:
with self.firewall_policy() as fwp:
fwp_id = fwp['firewall_policy']['id']
fr_id = fr['firewall_rule']['id']
fw_rule_ids = [fr_id]
data = {'firewall_policy':
{'firewall_rules': fw_rule_ids}}
req = self.new_update_request('firewall_policies', data,
fwp_id)
req.get_response(self.ext_api)
with self.firewall(
firewall_policy_id=fwp_id,
admin_state_up=test_db_firewall.ADMIN_STATE_UP
):
data = {'firewall_rule': {'protocol': 'udp'}}
req = self.new_update_request('firewall_rules',
data, fr_id)
res = req.get_response(self.ext_api)
self.assertEqual(exc.HTTPConflict.code, res.status_int)
def test_delete_firewall_with_no_routers(self):
ctx = context.get_admin_context()
# stop the AgentRPC patch for this one to test pending states
self.agentapi_del_fw_p.stop()
with self.firewall_policy() as fwp:
fwp_id = fwp['firewall_policy']['id']
with self.firewall(
firewall_policy_id=fwp_id,
admin_state_up=test_db_firewall.ADMIN_STATE_UP,
do_delete=False
) as fw:
fw_id = fw['firewall']['id']
req = self.new_delete_request('firewalls', fw_id)
res = req.get_response(self.ext_api)
self.assertEqual(exc.HTTPNoContent.code, res.status_int)
self.assertRaises(firewall.FirewallNotFound,
self.plugin.get_firewall,
ctx, fw_id)
def test_delete_firewall_after_agent_delete(self):
ctx = context.get_admin_context()
with self.firewall_policy() as fwp:
fwp_id = fwp['firewall_policy']['id']
with self.firewall(firewall_policy_id=fwp_id,
do_delete=False) as fw:
fw_id = fw['firewall']['id']
req = self.new_delete_request('firewalls', fw_id)
res = req.get_response(self.ext_api)
self.assertEqual(exc.HTTPNoContent.code, res.status_int)
self.assertRaises(firewall.FirewallNotFound,
self.plugin.get_firewall,
ctx, fw_id)
def test_make_firewall_dict_with_in_place_rules(self):
ctx = context.get_admin_context()
with self.firewall_rule(name='fwr1') as fwr1, \
self.firewall_rule(name='fwr2') as fwr2, \
self.firewall_rule(name='fwr3') as fwr3:
with self.firewall_policy() as fwp:
fr = [fwr1, fwr2, fwr3]
fwp_id = fwp['firewall_policy']['id']
fw_rule_ids = [r['firewall_rule']['id'] for r in fr]
data = {'firewall_policy':
{'firewall_rules': fw_rule_ids}}
req = self.new_update_request('firewall_policies', data,
fwp_id)
req.get_response(self.ext_api)
attrs = self._get_test_firewall_attrs()
attrs['firewall_policy_id'] = fwp_id
with self.firewall(
firewall_policy_id=fwp_id,
admin_state_up=test_db_firewall.ADMIN_STATE_UP,
router_ids=[]
) as fw:
fw_id = fw['firewall']['id']
fw_rules = (
self.plugin._make_firewall_dict_with_rules(ctx,
fw_id)
)
self.assertEqual(fw_id, fw_rules['id'])
self._compare_firewall_rule_lists(
fwp_id, fr, fw_rules['firewall_rule_list'])
def test_make_firewall_dict_with_in_place_rules_no_policy(self):
ctx = context.get_admin_context()
with self.firewall() as fw:
fw_id = fw['firewall']['id']
fw_rules = self.plugin._make_firewall_dict_with_rules(ctx, fw_id)
self.assertEqual([], fw_rules['firewall_rule_list'])
def test_list_firewalls(self):
with self.firewall_policy() as fwp:
fwp_id = fwp['firewall_policy']['id']
with self.firewall(name='fw1', firewall_policy_id=fwp_id,
description='fw') as fwalls:
self._test_list_resources('firewall', [fwalls],
query_params='description=fw')
def test_insert_rule(self):
ctx = context.get_admin_context()
with self.firewall_rule() as fwr:
fr_id = fwr['firewall_rule']['id']
rule_info = {'firewall_rule_id': fr_id}
with self.firewall_policy() as fwp:
fwp_id = fwp['firewall_policy']['id']
with self.firewall(firewall_policy_id=fwp_id) as fw:
fw_id = fw['firewall']['id']
self.plugin.insert_rule(ctx, fwp_id, rule_info)
fw_rules = self.plugin._make_firewall_dict_with_rules(
ctx, fw_id)
self.assertEqual(1, len(fw_rules['firewall_rule_list']))
self.assertEqual(fr_id,
fw_rules['firewall_rule_list'][0]['id'])
def test_insert_rule_notif(self):
ctx = context.get_admin_context()
with self.firewall_rule() as fwr:
fr_id = fwr['firewall_rule']['id']
rule_info = {'firewall_rule_id': fr_id}
with self.firewall_policy() as fwp:
fwp_id = fwp['firewall_policy']['id']
with self.firewall(firewall_policy_id=fwp_id):
self.plugin.insert_rule(ctx, fwp_id, rule_info)
notifications = fake_notifier.NOTIFICATIONS
expected_event_type = 'firewall_policy.update.insert_rule'
event_types = [event['event_type'] for event in notifications]
self.assertIn(expected_event_type, event_types)
def test_remove_rule(self):
ctx = context.get_admin_context()
with self.firewall_rule() as fwr:
fr_id = fwr['firewall_rule']['id']
rule_info = {'firewall_rule_id': fr_id}
with self.firewall_policy(firewall_rules=[fr_id]) as fwp:
fwp_id = fwp['firewall_policy']['id']
with self.firewall(firewall_policy_id=fwp_id) as fw:
fw_id = fw['firewall']['id']
self.plugin.remove_rule(ctx, fwp_id, rule_info)
fw_rules = self.plugin._make_firewall_dict_with_rules(
ctx, fw_id)
self.assertEqual([], fw_rules['firewall_rule_list'])
def test_remove_rule_notif(self):
ctx = context.get_admin_context()
with self.firewall_rule() as fwr:
fr_id = fwr['firewall_rule']['id']
rule_info = {'firewall_rule_id': fr_id}
with self.firewall_policy(firewall_rules=[fr_id]) as fwp:
fwp_id = fwp['firewall_policy']['id']
with self.firewall(firewall_policy_id=fwp_id):
self.plugin.remove_rule(ctx, fwp_id, rule_info)
notifications = fake_notifier.NOTIFICATIONS
expected_event_type = 'firewall_policy.update.remove_rule'
event_types = [event['event_type'] for event in notifications]
self.assertIn(expected_event_type, event_types)
def test_firewall_quota_lower(self):
"""Test quota using overridden value."""
cfg.CONF.set_override('quota_firewall', 3, group='QUOTAS')
with self.firewall(name='quota1'), \
self.firewall(name='quota2'), \
self.firewall(name='quota3'):
data = {'firewall': {'name': 'quota4',
'firewall_policy_id': None,
'tenant_id': self._tenant_id,
'shared': False}}
req = self.new_create_request('firewalls', data, 'json')
res = req.get_response(self.ext_api)
self.assertIn('Quota exceeded', res.body.decode('utf-8'))
self.assertEqual(exc.HTTPConflict.code, res.status_int)
def test_firewall_quota_default(self):
"""Test quota using default value."""
with self.firewall(name='quota1'), \
self.firewall(name='quota2'), \
self.firewall(name='quota3'), \
self.firewall(name='quota4'), \
self.firewall(name='quota5'), \
self.firewall(name='quota6'), \
self.firewall(name='quota7'), \
self.firewall(name='quota8'), \
self.firewall(name='quota9'), \
self.firewall(name='quota10'):
data = {'firewall': {'name': 'quota11',
'firewall_policy_id': None,
'tenant_id': self._tenant_id,
'shared': False}}
req = self.new_create_request('firewalls', data, 'json')
res = req.get_response(self.ext_api)
self.assertIn('Quota exceeded', res.body.decode('utf-8'))
self.assertEqual(exc.HTTPConflict.code, res.status_int)
neutron-fwaas-8.0.0/neutron_fwaas/tests/unit/services/__init__.py 0000664 0005670 0005671 00000000000 12701407720 026367 0 ustar jenkins jenkins 0000000 0000000 neutron-fwaas-8.0.0/neutron_fwaas/tests/unit/extensions/ 0000775 0005670 0005671 00000000000 12701410073 024637 5 ustar jenkins jenkins 0000000 0000000 neutron-fwaas-8.0.0/neutron_fwaas/tests/unit/extensions/__init__.py 0000664 0005670 0005671 00000000000 12701407720 026743 0 ustar jenkins jenkins 0000000 0000000 neutron-fwaas-8.0.0/neutron_fwaas/tests/unit/extensions/test_firewall.py 0000664 0005670 0005671 00000064530 12701407720 030072 0 ustar jenkins jenkins 0000000 0000000 # Copyright 2013 Big Switch Networks, Inc.
# All Rights Reserved.
#
# 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.
import copy
import mock
from neutron.api.v2 import attributes as attr
from neutron.plugins.common import constants
from neutron.tests import base
from neutron.tests.unit.api.v2 import test_base as test_api_v2
from neutron.tests.unit.extensions import base as test_api_v2_extension
from oslo_utils import uuidutils
from webob import exc
import webtest
from neutron_fwaas.extensions import firewall
_uuid = uuidutils.generate_uuid
_get_path = test_api_v2._get_path
_long_name = 'x' * (attr.NAME_MAX_LEN + 1)
_long_description = 'y' * (attr.DESCRIPTION_MAX_LEN + 1)
class FirewallExtensionTestCase(test_api_v2_extension.ExtensionTestCase):
fmt = 'json'
def setUp(self):
super(FirewallExtensionTestCase, self).setUp()
plural_mappings = {'firewall_policy': 'firewall_policies'}
self._setUpExtension(
'neutron_fwaas.extensions.firewall.FirewallPluginBase',
constants.FIREWALL, firewall.RESOURCE_ATTRIBUTE_MAP,
firewall.Firewall, 'fw', plural_mappings=plural_mappings)
def test_create_firewall(self):
fw_id = _uuid()
data = {'firewall': {'description': 'descr_firewall1',
'name': 'firewall1',
'admin_state_up': True,
'firewall_policy_id': _uuid(),
'shared': False,
'tenant_id': _uuid()}}
return_value = copy.copy(data['firewall'])
return_value.update({'id': fw_id})
# since 'shared' is hidden
del return_value['shared']
instance = self.plugin.return_value
instance.create_firewall.return_value = return_value
res = self.api.post(_get_path('fw/firewalls', fmt=self.fmt),
self.serialize(data),
content_type='application/%s' % self.fmt)
instance.create_firewall.assert_called_with(mock.ANY,
firewall=data)
self.assertEqual(exc.HTTPCreated.code, res.status_int)
res = self.deserialize(res)
self.assertIn('firewall', res)
self.assertEqual(return_value, res['firewall'])
def test_create_firewall_invalid_long_name(self):
data = {'firewall': {'description': 'descr_firewall1',
'name': _long_name,
'admin_state_up': True,
'firewall_policy_id': _uuid(),
'shared': False,
'tenant_id': _uuid()}}
res = self.api.post(_get_path('fw/firewalls', fmt=self.fmt),
self.serialize(data),
content_type='application/%s' % self.fmt,
status=exc.HTTPBadRequest.code)
self.assertIn('Invalid input for name', res.body.decode('utf-8'))
def test_create_firewall_invalid_long_description(self):
data = {'firewall': {'description': _long_description,
'name': 'firewall1',
'admin_state_up': True,
'firewall_policy_id': _uuid(),
'shared': False,
'tenant_id': _uuid()}}
res = self.api.post(_get_path('fw/firewalls', fmt=self.fmt),
self.serialize(data),
content_type='application/%s' % self.fmt,
status=exc.HTTPBadRequest.code)
self.assertIn('Invalid input for description',
res.body.decode('utf-8'))
def test_firewall_list(self):
fw_id = _uuid()
return_value = [{'tenant_id': _uuid(),
'id': fw_id}]
instance = self.plugin.return_value
instance.get_firewalls.return_value = return_value
res = self.api.get(_get_path('fw/firewalls', fmt=self.fmt))
instance.get_firewalls.assert_called_with(mock.ANY,
fields=mock.ANY,
filters=mock.ANY)
self.assertEqual(exc.HTTPOk.code, res.status_int)
def test_firewall_get(self):
fw_id = _uuid()
return_value = {'tenant_id': _uuid(),
'id': fw_id}
instance = self.plugin.return_value
instance.get_firewall.return_value = return_value
res = self.api.get(_get_path('fw/firewalls',
id=fw_id, fmt=self.fmt))
instance.get_firewall.assert_called_with(mock.ANY,
fw_id,
fields=mock.ANY)
self.assertEqual(exc.HTTPOk.code, res.status_int)
res = self.deserialize(res)
self.assertIn('firewall', res)
self.assertEqual(return_value, res['firewall'])
def test_firewall_update(self):
fw_id = _uuid()
update_data = {'firewall': {'name': 'new_name'}}
return_value = {'tenant_id': _uuid(),
'id': fw_id}
instance = self.plugin.return_value
instance.update_firewall.return_value = return_value
res = self.api.put(_get_path('fw/firewalls', id=fw_id,
fmt=self.fmt),
self.serialize(update_data))
instance.update_firewall.assert_called_with(mock.ANY, fw_id,
firewall=update_data)
self.assertEqual(exc.HTTPOk.code, res.status_int)
res = self.deserialize(res)
self.assertIn('firewall', res)
self.assertEqual(return_value, res['firewall'])
def test_firewall_delete(self):
self._test_entity_delete('firewall')
def _test_create_firewall_rule(self, src_port, dst_port):
rule_id = _uuid()
data = {'firewall_rule': {'description': 'descr_firewall_rule1',
'name': 'rule1',
'shared': False,
'protocol': 'tcp',
'ip_version': 4,
'source_ip_address': '192.168.0.1',
'destination_ip_address': '127.0.0.1',
'source_port': src_port,
'destination_port': dst_port,
'action': 'allow',
'enabled': True,
'tenant_id': _uuid()}}
expected_ret_val = copy.copy(data['firewall_rule'])
expected_ret_val['source_port'] = str(src_port)
expected_ret_val['destination_port'] = str(dst_port)
expected_call_args = copy.copy(expected_ret_val)
expected_ret_val['id'] = rule_id
instance = self.plugin.return_value
instance.create_firewall_rule.return_value = expected_ret_val
res = self.api.post(_get_path('fw/firewall_rules', fmt=self.fmt),
self.serialize(data),
content_type='application/%s' % self.fmt)
instance.create_firewall_rule.assert_called_with(
mock.ANY,
firewall_rule={'firewall_rule': expected_call_args})
self.assertEqual(exc.HTTPCreated.code, res.status_int)
res = self.deserialize(res)
self.assertIn('firewall_rule', res)
self.assertEqual(expected_ret_val, res['firewall_rule'])
def test_create_firewall_rule_with_integer_ports(self):
self._test_create_firewall_rule(1, 10)
def test_create_firewall_rule_with_string_ports(self):
self._test_create_firewall_rule('1', '10')
def test_create_firewall_rule_with_port_range(self):
self._test_create_firewall_rule('1:20', '30:40')
def test_create_firewall_rule_invalid_long_name(self):
data = {'firewall_rule': {'description': 'descr_firewall_rule1',
'name': _long_name,
'shared': False,
'protocol': 'tcp',
'ip_version': 4,
'source_ip_address': '192.168.0.1',
'destination_ip_address': '127.0.0.1',
'source_port': 1,
'destination_port': 1,
'action': 'allow',
'enabled': True,
'tenant_id': _uuid()}}
res = self.api.post(_get_path('fw/firewall_rules', fmt=self.fmt),
self.serialize(data),
content_type='application/%s' % self.fmt,
status=exc.HTTPBadRequest.code)
self.assertIn('Invalid input for name', res.body.decode('utf-8'))
def test_create_firewall_rule_invalid_long_description(self):
data = {'firewall_rule': {'description': _long_description,
'name': 'rule1',
'shared': False,
'protocol': 'tcp',
'ip_version': 4,
'source_ip_address': '192.168.0.1',
'destination_ip_address': '127.0.0.1',
'source_port': 1,
'destination_port': 1,
'action': 'allow',
'enabled': True,
'tenant_id': _uuid()}}
res = self.api.post(_get_path('fw/firewall_rules', fmt=self.fmt),
self.serialize(data),
content_type='application/%s' % self.fmt,
status=exc.HTTPBadRequest.code)
self.assertIn('Invalid input for description',
res.body.decode('utf-8'))
def test_firewall_rule_list(self):
rule_id = _uuid()
return_value = [{'tenant_id': _uuid(),
'id': rule_id}]
instance = self.plugin.return_value
instance.get_firewall_rules.return_value = return_value
res = self.api.get(_get_path('fw/firewall_rules', fmt=self.fmt))
instance.get_firewall_rules.assert_called_with(mock.ANY,
fields=mock.ANY,
filters=mock.ANY)
self.assertEqual(exc.HTTPOk.code, res.status_int)
def test_firewall_rule_get(self):
rule_id = _uuid()
return_value = {'tenant_id': _uuid(),
'id': rule_id}
instance = self.plugin.return_value
instance.get_firewall_rule.return_value = return_value
res = self.api.get(_get_path('fw/firewall_rules',
id=rule_id, fmt=self.fmt))
instance.get_firewall_rule.assert_called_with(mock.ANY,
rule_id,
fields=mock.ANY)
self.assertEqual(exc.HTTPOk.code, res.status_int)
res = self.deserialize(res)
self.assertIn('firewall_rule', res)
self.assertEqual(return_value, res['firewall_rule'])
def test_firewall_rule_update(self):
rule_id = _uuid()
update_data = {'firewall_rule': {'action': 'deny'}}
return_value = {'tenant_id': _uuid(),
'id': rule_id}
instance = self.plugin.return_value
instance.update_firewall_rule.return_value = return_value
res = self.api.put(_get_path('fw/firewall_rules', id=rule_id,
fmt=self.fmt),
self.serialize(update_data))
instance.update_firewall_rule.assert_called_with(
mock.ANY,
rule_id,
firewall_rule=update_data)
self.assertEqual(exc.HTTPOk.code, res.status_int)
res = self.deserialize(res)
self.assertIn('firewall_rule', res)
self.assertEqual(return_value, res['firewall_rule'])
def test_firewall_rule_delete(self):
self._test_entity_delete('firewall_rule')
def test_create_firewall_policy(self):
policy_id = _uuid()
data = {'firewall_policy': {'description': 'descr_firewall_policy1',
'name': 'new_fw_policy1',
'shared': False,
'firewall_rules': [_uuid(), _uuid()],
'audited': False,
'tenant_id': _uuid()}}
return_value = copy.copy(data['firewall_policy'])
return_value.update({'id': policy_id})
instance = self.plugin.return_value
instance.create_firewall_policy.return_value = return_value
res = self.api.post(_get_path('fw/firewall_policies',
fmt=self.fmt),
self.serialize(data),
content_type='application/%s' % self.fmt)
instance.create_firewall_policy.assert_called_with(
mock.ANY,
firewall_policy=data)
self.assertEqual(exc.HTTPCreated.code, res.status_int)
res = self.deserialize(res)
self.assertIn('firewall_policy', res)
self.assertEqual(return_value, res['firewall_policy'])
def test_create_firewall_policy_invalid_long_name(self):
data = {'firewall_policy': {'description': 'descr_firewall_policy1',
'name': _long_name,
'shared': False,
'firewall_rules': [_uuid(), _uuid()],
'audited': False,
'tenant_id': _uuid()}}
res = self.api.post(_get_path('fw/firewall_policies',
fmt=self.fmt),
self.serialize(data),
content_type='application/%s' % self.fmt,
status=exc.HTTPBadRequest.code)
self.assertIn('Invalid input for name', res.body.decode('utf-8'))
def test_create_firewall_policy_invalid_long_description(self):
data = {'firewall_policy': {'description': _long_description,
'name': 'new_fw_policy1',
'shared': False,
'firewall_rules': [_uuid(), _uuid()],
'audited': False,
'tenant_id': _uuid()}}
res = self.api.post(_get_path('fw/firewall_policies',
fmt=self.fmt),
self.serialize(data),
content_type='application/%s' % self.fmt,
status=exc.HTTPBadRequest.code)
self.assertIn('Invalid input for description',
res.body.decode('utf-8'))
def test_firewall_policy_list(self):
policy_id = _uuid()
return_value = [{'tenant_id': _uuid(),
'id': policy_id}]
instance = self.plugin.return_value
instance.get_firewall_policies.return_value = return_value
res = self.api.get(_get_path('fw/firewall_policies',
fmt=self.fmt))
instance.get_firewall_policies.assert_called_with(mock.ANY,
fields=mock.ANY,
filters=mock.ANY)
self.assertEqual(exc.HTTPOk.code, res.status_int)
def test_firewall_policy_get(self):
policy_id = _uuid()
return_value = {'tenant_id': _uuid(),
'id': policy_id}
instance = self.plugin.return_value
instance.get_firewall_policy.return_value = return_value
res = self.api.get(_get_path('fw/firewall_policies',
id=policy_id, fmt=self.fmt))
instance.get_firewall_policy.assert_called_with(mock.ANY,
policy_id,
fields=mock.ANY)
self.assertEqual(exc.HTTPOk.code, res.status_int)
res = self.deserialize(res)
self.assertIn('firewall_policy', res)
self.assertEqual(return_value, res['firewall_policy'])
def test_firewall_policy_update(self):
policy_id = _uuid()
update_data = {'firewall_policy': {'audited': True}}
return_value = {'tenant_id': _uuid(),
'id': policy_id}
instance = self.plugin.return_value
instance.update_firewall_policy.return_value = return_value
res = self.api.put(_get_path('fw/firewall_policies',
id=policy_id,
fmt=self.fmt),
self.serialize(update_data))
instance.update_firewall_policy.assert_called_with(
mock.ANY,
policy_id,
firewall_policy=update_data)
self.assertEqual(exc.HTTPOk.code, res.status_int)
res = self.deserialize(res)
self.assertIn('firewall_policy', res)
self.assertEqual(return_value, res['firewall_policy'])
def test_firewall_policy_update_malformed_rules(self):
# emulating client request when no rule uuids are provided for
# --firewall_rules parameter
update_data = {'firewall_policy': {'firewall_rules': True}}
# have to check for generic AppError
self.assertRaises(
webtest.AppError,
self.api.put,
_get_path('fw/firewall_policies', id=_uuid(), fmt=self.fmt),
self.serialize(update_data))
def test_firewall_policy_delete(self):
self._test_entity_delete('firewall_policy')
def test_firewall_policy_insert_rule(self):
firewall_policy_id = _uuid()
firewall_rule_id = _uuid()
ref_firewall_rule_id = _uuid()
insert_data = {'firewall_rule_id': firewall_rule_id,
'insert_before': ref_firewall_rule_id,
'insert_after': None}
return_value = {'firewall_policy':
{'tenant_id': _uuid(),
'id': firewall_policy_id,
'firewall_rules': [ref_firewall_rule_id,
firewall_rule_id]}}
instance = self.plugin.return_value
instance.insert_rule.return_value = return_value
path = _get_path('fw/firewall_policies', id=firewall_policy_id,
action="insert_rule",
fmt=self.fmt)
res = self.api.put(path, self.serialize(insert_data))
instance.insert_rule.assert_called_with(mock.ANY, firewall_policy_id,
insert_data)
self.assertEqual(exc.HTTPOk.code, res.status_int)
res = self.deserialize(res)
self.assertEqual(return_value, res)
def test_firewall_policy_remove_rule(self):
firewall_policy_id = _uuid()
firewall_rule_id = _uuid()
remove_data = {'firewall_rule_id': firewall_rule_id}
return_value = {'firewall_policy':
{'tenant_id': _uuid(),
'id': firewall_policy_id,
'firewall_rules': []}}
instance = self.plugin.return_value
instance.remove_rule.return_value = return_value
path = _get_path('fw/firewall_policies', id=firewall_policy_id,
action="remove_rule",
fmt=self.fmt)
res = self.api.put(path, self.serialize(remove_data))
instance.remove_rule.assert_called_with(mock.ANY, firewall_policy_id,
remove_data)
self.assertEqual(exc.HTTPOk.code, res.status_int)
res = self.deserialize(res)
self.assertEqual(return_value, res)
class TestFirewallAttributeValidators(base.BaseTestCase):
def test_validate_port_range(self):
msg = firewall._validate_port_range(None)
self.assertIsNone(msg)
msg = firewall._validate_port_range('10')
self.assertIsNone(msg)
msg = firewall._validate_port_range(10)
self.assertIsNone(msg)
msg = firewall._validate_port_range(-1)
self.assertEqual("Invalid port '-1'", msg)
msg = firewall._validate_port_range('66000')
self.assertEqual("Invalid port '66000'", msg)
msg = firewall._validate_port_range('10:20')
self.assertIsNone(msg)
msg = firewall._validate_port_range('1:65535')
self.assertIsNone(msg)
msg = firewall._validate_port_range('0:65535')
self.assertEqual("Invalid port '0'", msg)
msg = firewall._validate_port_range('1:65536')
self.assertEqual("Invalid port '65536'", msg)
msg = firewall._validate_port_range('abc:efg')
self.assertEqual("Port 'abc' is not a valid number", msg)
msg = firewall._validate_port_range('1:efg')
self.assertEqual("Port 'efg' is not a valid number", msg)
msg = firewall._validate_port_range('-1:10')
self.assertEqual("Invalid port '-1'", msg)
msg = firewall._validate_port_range('66000:10')
self.assertEqual("Invalid port '66000'", msg)
msg = firewall._validate_port_range('10:66000')
self.assertEqual("Invalid port '66000'", msg)
msg = firewall._validate_port_range('1:-10')
self.assertEqual("Invalid port '-10'", msg)
def test_validate_ip_or_subnet_or_none(self):
msg = firewall._validate_ip_or_subnet_or_none(None)
self.assertIsNone(msg)
msg = firewall._validate_ip_or_subnet_or_none('1.1.1.1')
self.assertIsNone(msg)
msg = firewall._validate_ip_or_subnet_or_none('1.1.1.0/24')
self.assertIsNone(msg)
ip_addr = '1111.1.1.1'
msg = firewall._validate_ip_or_subnet_or_none(ip_addr)
self.assertEqual(
("'%s' is not a valid IP address and "
"'%s' is not a valid IP subnet")
% (ip_addr,
ip_addr),
msg)
ip_addr = '1.1.1.1 has whitespace'
msg = firewall._validate_ip_or_subnet_or_none(ip_addr)
self.assertEqual(
("'%s' is not a valid IP address and "
"'%s' is not a valid IP subnet") % (ip_addr,
ip_addr),
msg)
ip_addr = '111.1.1.1\twhitespace'
msg = firewall._validate_ip_or_subnet_or_none(ip_addr)
self.assertEqual(
("'%s' is not a valid IP address and "
"'%s' is not a valid IP subnet") % (ip_addr,
ip_addr),
msg)
ip_addr = '111.1.1.1\nwhitespace'
msg = firewall._validate_ip_or_subnet_or_none(ip_addr)
self.assertEqual(
("'%s' is not a valid IP address and "
"'%s' is not a valid IP subnet") % (ip_addr,
ip_addr),
msg)
# Valid - IPv4
cidr = "10.0.2.0/24"
msg = firewall._validate_ip_or_subnet_or_none(cidr, None)
self.assertIsNone(msg)
# Valid - IPv6 without final octets
cidr = "fe80::/24"
msg = firewall._validate_ip_or_subnet_or_none(cidr, None)
self.assertIsNone(msg)
# Valid - IPv6 with final octets
cidr = "fe80::0/24"
msg = firewall._validate_ip_or_subnet_or_none(cidr, None)
self.assertIsNone(msg)
cidr = "fe80::"
msg = firewall._validate_ip_or_subnet_or_none(cidr, None)
self.assertIsNone(msg)
# Invalid - IPv6 with final octets, missing mask
cidr = "fe80::0"
msg = firewall._validate_ip_or_subnet_or_none(cidr, None)
self.assertIsNone(msg)
# Invalid - Address format error
cidr = 'invalid'
msg = firewall._validate_ip_or_subnet_or_none(cidr, None)
self.assertEqual(
("'%s' is not a valid IP address and "
"'%s' is not a valid IP subnet") % (cidr,
cidr),
msg)
class TestFirewallConvertProtocols(base.BaseTestCase):
def test_convert_protocol_digit(self):
res = firewall.convert_protocol("0")
self.assertEqual(0, res)
res = firewall.convert_protocol("255")
self.assertEqual(255, res)
def test_convert_protocol_invalid_digit(self):
res = lambda: firewall.convert_protocol("-1")
self.assertRaises(firewall.FirewallRuleInvalidProtocol, res)
res = lambda: firewall.convert_protocol("256")
self.assertRaises(firewall.FirewallRuleInvalidProtocol, res)
def test_convert_protocol_name(self):
res = firewall.convert_protocol("tcp")
self.assertEqual("tcp", res)
res = firewall.convert_protocol("UDP")
self.assertEqual("udp", res)
res = firewall.convert_protocol("Icmp")
self.assertEqual("icmp", res)
def test_convert_protocol_invalid_name(self):
res = lambda: firewall.convert_protocol("foo")
self.assertRaises(firewall.FirewallRuleInvalidProtocol, res)
class TestConvertActionToCaseInsensitive(base.BaseTestCase):
def test_convert_action_to_case_insensitive_none(self):
res = firewall.convert_action_to_case_insensitive(None)
self.assertIsNone(res)
def test_convert_action_to_case_insensitive_value(self):
res = firewall.convert_action_to_case_insensitive("foo")
self.assertEqual("foo", res)
res = firewall.convert_action_to_case_insensitive("Bar")
self.assertEqual("bar", res)
res = firewall.convert_action_to_case_insensitive("BAZ")
self.assertEqual("baz", res)
neutron-fwaas-8.0.0/neutron_fwaas/tests/unit/db/ 0000775 0005670 0005671 00000000000 12701410073 023025 5 ustar jenkins jenkins 0000000 0000000 neutron-fwaas-8.0.0/neutron_fwaas/tests/unit/db/firewall/ 0000775 0005670 0005671 00000000000 12701410073 024632 5 ustar jenkins jenkins 0000000 0000000 neutron-fwaas-8.0.0/neutron_fwaas/tests/unit/db/firewall/__init__.py 0000664 0005670 0005671 00000000000 12701407720 026736 0 ustar jenkins jenkins 0000000 0000000 neutron-fwaas-8.0.0/neutron_fwaas/tests/unit/db/firewall/test_firewall_db.py 0000664 0005670 0005671 00000217275 12701407720 030540 0 ustar jenkins jenkins 0000000 0000000 # Copyright 2013 Big Switch Networks, Inc.
# All Rights Reserved.
#
# 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.
import contextlib
import mock
from neutron.api import extensions as api_ext
from neutron.common import config
from neutron import context
import neutron.extensions as nextensions
from neutron.extensions import l3
from neutron import manager
from neutron.plugins.common import constants
from oslo_config import cfg
from oslo_utils import importutils
from oslo_utils import uuidutils
import six
import webob.exc
from neutron_fwaas.db.firewall import firewall_db as fdb
from neutron_fwaas import extensions
from neutron_fwaas.extensions import firewall
from neutron_fwaas.services.firewall import fwaas_plugin
from neutron_fwaas.tests import base
DB_FW_PLUGIN_KLASS = (
"neutron_fwaas.db.firewall.firewall_db.Firewall_db_mixin"
)
FWAAS_PLUGIN = 'neutron_fwaas.services.firewall.fwaas_plugin'
DELETEFW_PATH = FWAAS_PLUGIN + '.FirewallAgentApi.delete_firewall'
extensions_path = ':'.join(extensions.__path__ + nextensions.__path__)
DESCRIPTION = 'default description'
SHARED = True
PROTOCOL = 'tcp'
IP_VERSION = 4
SOURCE_IP_ADDRESS_RAW = '1.1.1.1'
DESTINATION_IP_ADDRESS_RAW = '2.2.2.2'
SOURCE_PORT = '55000:56000'
DESTINATION_PORT = '56000:57000'
ACTION = 'allow'
AUDITED = True
ENABLED = True
ADMIN_STATE_UP = True
class FakeAgentApi(fwaas_plugin.FirewallCallbacks):
"""
This class used to mock the AgentAPI delete method inherits from
FirewallCallbacks because it needs access to the firewall_deleted method.
The delete_firewall method belongs to the FirewallAgentApi, which has
no access to the firewall_deleted method normally because it's not
responsible for deleting the firewall from the DB. However, it needs
to in the unit tests since there is no agent to call back.
"""
def __init__(self):
pass
def delete_firewall(self, context, firewall, **kwargs):
self.plugin = manager.NeutronManager.get_service_plugins()['FIREWALL']
self.firewall_deleted(context, firewall['id'], **kwargs)
class FirewallPluginDbTestCase(base.NeutronDbPluginV2TestCase):
resource_prefix_map = dict(
(k, firewall.FIREWALL_PREFIX)
for k in firewall.RESOURCE_ATTRIBUTE_MAP.keys()
)
def setUp(self, core_plugin=None, fw_plugin=None, ext_mgr=None):
self.agentapi_delf_p = mock.patch(DELETEFW_PATH, create=True,
new=FakeAgentApi().delete_firewall)
self.agentapi_delf_p.start()
if not fw_plugin:
fw_plugin = DB_FW_PLUGIN_KLASS
service_plugins = {'fw_plugin_name': fw_plugin}
fdb.Firewall_db_mixin.supported_extension_aliases = ["fwaas"]
fdb.Firewall_db_mixin.path_prefix = firewall.FIREWALL_PREFIX
super(FirewallPluginDbTestCase, self).setUp(
ext_mgr=ext_mgr,
service_plugins=service_plugins
)
if not ext_mgr:
self.plugin = importutils.import_object(fw_plugin)
ext_mgr = api_ext.PluginAwareExtensionManager(
extensions_path,
{constants.FIREWALL: self.plugin}
)
app = config.load_paste_app('extensions_test_app')
self.ext_api = api_ext.ExtensionMiddleware(app, ext_mgr=ext_mgr)
def _test_list_resources(self, resource, items,
neutron_context=None,
query_params=None):
if resource.endswith('y'):
resource_plural = resource.replace('y', 'ies')
else:
resource_plural = resource + 's'
res = self._list(resource_plural,
neutron_context=neutron_context,
query_params=query_params)
resource = resource.replace('-', '_')
self.assertEqual(
sorted([i[resource]['id'] for i in items]),
sorted([i['id'] for i in res[resource_plural]]))
def _get_test_firewall_rule_attrs(self, name='firewall_rule1'):
attrs = {'name': name,
'tenant_id': self._tenant_id,
'shared': SHARED,
'protocol': PROTOCOL,
'ip_version': IP_VERSION,
'source_ip_address': SOURCE_IP_ADDRESS_RAW,
'destination_ip_address': DESTINATION_IP_ADDRESS_RAW,
'source_port': SOURCE_PORT,
'destination_port': DESTINATION_PORT,
'action': ACTION,
'enabled': ENABLED}
return attrs
def _get_test_firewall_policy_attrs(self, name='firewall_policy1',
audited=AUDITED):
attrs = {'name': name,
'description': DESCRIPTION,
'tenant_id': self._tenant_id,
'shared': SHARED,
'firewall_rules': [],
'audited': audited}
return attrs
def _get_test_firewall_attrs(self, name='firewall_1',
status='PENDING_CREATE'):
attrs = {'name': name,
'tenant_id': self._tenant_id,
'admin_state_up': ADMIN_STATE_UP,
'status': status}
return attrs
def _create_firewall_policy(self, fmt, name, description, shared,
firewall_rules, audited,
expected_res_status=None, **kwargs):
tenant_id = kwargs.get('tenant_id', self._tenant_id)
data = {'firewall_policy': {'name': name,
'description': description,
'tenant_id': tenant_id,
'shared': shared,
'firewall_rules': firewall_rules,
'audited': audited}}
fw_policy_req = self.new_create_request('firewall_policies', data, fmt)
fw_policy_res = fw_policy_req.get_response(self.ext_api)
if expected_res_status:
self.assertEqual(expected_res_status, fw_policy_res.status_int)
return fw_policy_res
def _replace_firewall_status(self, attrs, old_status, new_status):
if attrs['status'] is old_status:
attrs['status'] = new_status
return attrs
@contextlib.contextmanager
def firewall_policy(self, fmt=None, name='firewall_policy1',
description=DESCRIPTION, shared=True,
firewall_rules=None, audited=True,
do_delete=True, **kwargs):
if firewall_rules is None:
firewall_rules = []
if not fmt:
fmt = self.fmt
res = self._create_firewall_policy(fmt, name, description, shared,
firewall_rules, audited,
**kwargs)
if res.status_int >= 400:
raise webob.exc.HTTPClientError(code=res.status_int)
firewall_policy = self.deserialize(fmt or self.fmt, res)
yield firewall_policy
if do_delete:
self._delete('firewall_policies',
firewall_policy['firewall_policy']['id'])
def _create_firewall_rule(self, fmt, name, shared, protocol,
ip_version, source_ip_address,
destination_ip_address, source_port,
destination_port, action, enabled,
expected_res_status=None, **kwargs):
tenant_id = kwargs.get('tenant_id', self._tenant_id)
data = {'firewall_rule': {'name': name,
'tenant_id': tenant_id,
'shared': shared,
'protocol': protocol,
'ip_version': ip_version,
'source_ip_address': source_ip_address,
'destination_ip_address':
destination_ip_address,
'source_port': source_port,
'destination_port': destination_port,
'action': action,
'enabled': enabled}}
fw_rule_req = self.new_create_request('firewall_rules', data, fmt)
fw_rule_res = fw_rule_req.get_response(self.ext_api)
if expected_res_status:
self.assertEqual(expected_res_status, fw_rule_res.status_int)
return fw_rule_res
@contextlib.contextmanager
def firewall_rule(self, fmt=None, name='firewall_rule1',
shared=SHARED, protocol=PROTOCOL, ip_version=IP_VERSION,
source_ip_address=SOURCE_IP_ADDRESS_RAW,
destination_ip_address=DESTINATION_IP_ADDRESS_RAW,
source_port=SOURCE_PORT,
destination_port=DESTINATION_PORT,
action=ACTION, enabled=ENABLED,
do_delete=True, **kwargs):
if not fmt:
fmt = self.fmt
res = self._create_firewall_rule(fmt, name, shared, protocol,
ip_version, source_ip_address,
destination_ip_address,
source_port, destination_port,
action, enabled, **kwargs)
if res.status_int >= 400:
raise webob.exc.HTTPClientError(code=res.status_int)
firewall_rule = self.deserialize(fmt or self.fmt, res)
yield firewall_rule
if do_delete:
self._delete('firewall_rules',
firewall_rule['firewall_rule']['id'])
def _create_firewall(self, fmt, name, description, firewall_policy_id,
admin_state_up=True, expected_res_status=None,
**kwargs):
tenant_id = kwargs.get('tenant_id', self._tenant_id)
if firewall_policy_id is None:
res = self._create_firewall_policy(fmt, 'fwp',
description=DESCRIPTION,
shared=True,
firewall_rules=[],
tenant_id=tenant_id,
audited=AUDITED)
firewall_policy = self.deserialize(fmt or self.fmt, res)
firewall_policy_id = firewall_policy["firewall_policy"]["id"]
data = {'firewall': {'name': name,
'description': description,
'firewall_policy_id': firewall_policy_id,
'admin_state_up': admin_state_up}}
ctx = kwargs.get('context', None)
if ctx is None or ctx.is_admin:
data['firewall'].update({'tenant_id': tenant_id})
firewall_req = self.new_create_request('firewalls', data, fmt,
context=ctx)
firewall_res = firewall_req.get_response(self.ext_api)
if expected_res_status:
self.assertEqual(expected_res_status, firewall_res.status_int)
return firewall_res
@contextlib.contextmanager
def firewall(self, fmt=None, name='firewall_1', description=DESCRIPTION,
firewall_policy_id=None, admin_state_up=True,
do_delete=True, **kwargs):
if not fmt:
fmt = self.fmt
res = self._create_firewall(fmt, name, description, firewall_policy_id,
admin_state_up, **kwargs)
if res.status_int >= 400:
raise webob.exc.HTTPClientError(code=res.status_int)
firewall = self.deserialize(fmt or self.fmt, res)
yield firewall
if do_delete:
self._delete('firewalls', firewall['firewall']['id'])
def _rule_action(self, action, id, firewall_rule_id, insert_before=None,
insert_after=None, expected_code=webob.exc.HTTPOk.code,
expected_body=None, body_data=None):
# We intentionally do this check for None since we want to distinguish
# from empty dictionary
if body_data is None:
if action == 'insert':
body_data = {'firewall_rule_id': firewall_rule_id,
'insert_before': insert_before,
'insert_after': insert_after}
else:
body_data = {'firewall_rule_id': firewall_rule_id}
req = self.new_action_request('firewall_policies',
body_data, id,
"%s_rule" % action)
res = req.get_response(self.ext_api)
self.assertEqual(expected_code, res.status_int)
response = self.deserialize(self.fmt, res)
if expected_body:
self.assertEqual(expected_body, response)
return response
def _compare_firewall_rule_lists(self, firewall_policy_id,
observed_list, expected_list):
position = 0
for r1, r2 in zip(observed_list, expected_list):
rule = r1['firewall_rule']
rule['firewall_policy_id'] = firewall_policy_id
position += 1
rule['position'] = position
for k in rule:
self.assertEqual(r2[k], rule[k])
class TestFirewallDBPlugin(FirewallPluginDbTestCase):
def test_create_firewall_policy(self):
name = "firewall_policy1"
attrs = self._get_test_firewall_policy_attrs(name)
with self.firewall_policy(name=name, shared=SHARED,
firewall_rules=None,
audited=AUDITED) as firewall_policy:
for k, v in six.iteritems(attrs):
self.assertEqual(v, firewall_policy['firewall_policy'][k])
def test_create_firewall_policy_with_rules(self):
name = "firewall_policy1"
attrs = self._get_test_firewall_policy_attrs(name)
with self.firewall_rule(name='fwr1') as fwr1, \
self.firewall_rule(name='fwr2') as fwr2, \
self.firewall_rule(name='fwr3') as fwr3:
fr = [fwr1, fwr2, fwr3]
fw_rule_ids = [r['firewall_rule']['id'] for r in fr]
attrs['firewall_rules'] = fw_rule_ids
with self.firewall_policy(name=name, shared=SHARED,
firewall_rules=fw_rule_ids,
audited=AUDITED) as fwp:
for k, v in six.iteritems(attrs):
self.assertEqual(v, fwp['firewall_policy'][k])
def test_create_admin_firewall_policy_with_other_tenant_rules(self):
with self.firewall_rule(shared=False) as fr:
fw_rule_ids = [fr['firewall_rule']['id']]
res = self._create_firewall_policy(None, 'firewall_policy1',
description=DESCRIPTION,
shared=SHARED,
firewall_rules=fw_rule_ids,
audited=AUDITED,
tenant_id='admin-tenant')
self.assertEqual(webob.exc.HTTPConflict.code, res.status_int)
def test_create_firewall_policy_with_previously_associated_rule(self):
with self.firewall_rule() as fwr:
fw_rule_ids = [fwr['firewall_rule']['id']]
with self.firewall_policy(firewall_rules=fw_rule_ids):
res = self._create_firewall_policy(
None, 'firewall_policy2', description=DESCRIPTION,
shared=SHARED, firewall_rules=fw_rule_ids,
audited=AUDITED)
self.assertEqual(409, res.status_int)
def test_create_shared_firewall_policy_with_unshared_rule(self):
with self.firewall_rule(shared=False) as fwr:
fw_rule_ids = [fwr['firewall_rule']['id']]
res = self._create_firewall_policy(
None, 'firewall_policy1', description=DESCRIPTION, shared=True,
firewall_rules=fw_rule_ids, audited=AUDITED)
self.assertEqual(webob.exc.HTTPConflict.code, res.status_int)
def test_show_firewall_policy(self):
name = "firewall_policy1"
attrs = self._get_test_firewall_policy_attrs(name)
with self.firewall_policy(name=name, shared=SHARED,
firewall_rules=None,
audited=AUDITED) as fwp:
req = self.new_show_request('firewall_policies',
fwp['firewall_policy']['id'],
fmt=self.fmt)
res = self.deserialize(self.fmt, req.get_response(self.ext_api))
for k, v in six.iteritems(attrs):
self.assertEqual(v, res['firewall_policy'][k])
def test_list_firewall_policies(self):
with self.firewall_policy(name='fwp1', description='fwp') as fwp1, \
self.firewall_policy(name='fwp2', description='fwp') as fwp2, \
self.firewall_policy(name='fwp3', description='fwp') as fwp3:
fw_policies = [fwp1, fwp2, fwp3]
self._test_list_resources('firewall_policy',
fw_policies,
query_params='description=fwp')
def test_update_firewall_policy(self):
name = "new_firewall_policy1"
attrs = self._get_test_firewall_policy_attrs(name, audited=False)
with self.firewall_policy(shared=SHARED,
firewall_rules=None,
audited=AUDITED) as fwp:
data = {'firewall_policy': {'name': name}}
req = self.new_update_request('firewall_policies', data,
fwp['firewall_policy']['id'])
res = self.deserialize(self.fmt, req.get_response(self.ext_api))
for k, v in six.iteritems(attrs):
self.assertEqual(v, res['firewall_policy'][k])
def _test_update_firewall_policy(self, with_audited):
with self.firewall_policy(name='firewall_policy1',
description='fwp',
audited=AUDITED) as fwp:
attrs = self._get_test_firewall_policy_attrs(audited=with_audited)
data = {'firewall_policy':
{'description': 'fw_p1'}}
if with_audited:
data['firewall_policy']['audited'] = 'True'
req = self.new_update_request('firewall_policies', data,
fwp['firewall_policy']['id'])
res = self.deserialize(self.fmt,
req.get_response(self.ext_api))
attrs['description'] = 'fw_p1'
for k, v in six.iteritems(attrs):
self.assertEqual(v, res['firewall_policy'][k])
def test_update_firewall_policy_set_audited_false(self):
self._test_update_firewall_policy(with_audited=False)
def test_update_firewall_policy_with_audited_set_true(self):
self._test_update_firewall_policy(with_audited=True)
def test_update_firewall_policy_with_rules(self):
attrs = self._get_test_firewall_policy_attrs()
with self.firewall_rule(name='fwr1') as fwr1, \
self.firewall_rule(name='fwr2') as fwr2, \
self.firewall_rule(name='fwr3') as fwr3:
with self.firewall_policy() as fwp:
fr = [fwr1, fwr2, fwr3]
fw_rule_ids = [r['firewall_rule']['id'] for r in fr]
attrs['firewall_rules'] = fw_rule_ids
data = {'firewall_policy':
{'firewall_rules': fw_rule_ids}}
req = self.new_update_request('firewall_policies', data,
fwp['firewall_policy']['id'])
res = self.deserialize(self.fmt,
req.get_response(self.ext_api))
attrs['audited'] = False
for k, v in six.iteritems(attrs):
self.assertEqual(v, res['firewall_policy'][k])
def test_update_firewall_policy_replace_rules(self):
attrs = self._get_test_firewall_policy_attrs()
with self.firewall_rule(name='fwr1') as fwr1, \
self.firewall_rule(name='fwr2') as fwr2, \
self.firewall_rule(name='fwr3') as fwr3, \
self.firewall_rule(name='fwr4') as fwr4:
frs = [fwr1, fwr2, fwr3, fwr4]
fr1 = frs[0:2]
fr2 = frs[2:4]
with self.firewall_policy() as fwp:
fw_rule_ids = [r['firewall_rule']['id'] for r in fr1]
data = {'firewall_policy':
{'firewall_rules': fw_rule_ids}}
req = self.new_update_request('firewall_policies', data,
fwp['firewall_policy']['id'])
req.get_response(self.ext_api)
fw_rule_ids = [r['firewall_rule']['id'] for r in fr2]
attrs['firewall_rules'] = fw_rule_ids
new_data = {'firewall_policy':
{'firewall_rules': fw_rule_ids}}
req = self.new_update_request('firewall_policies', new_data,
fwp['firewall_policy']['id'])
res = self.deserialize(self.fmt,
req.get_response(self.ext_api))
attrs['audited'] = False
for k, v in six.iteritems(attrs):
self.assertEqual(v, res['firewall_policy'][k])
def test_update_firewall_policy_reorder_rules(self):
attrs = self._get_test_firewall_policy_attrs()
with self.firewall_rule(name='fwr1') as fwr1, \
self.firewall_rule(name='fwr2') as fwr2, \
self.firewall_rule(name='fwr3') as fwr3, \
self.firewall_rule(name='fwr4') as fwr4:
fr = [fwr1, fwr2, fwr3, fwr4]
with self.firewall_policy() as fwp:
fw_rule_ids = [fr[2]['firewall_rule']['id'],
fr[3]['firewall_rule']['id']]
data = {'firewall_policy':
{'firewall_rules': fw_rule_ids}}
req = self.new_update_request('firewall_policies', data,
fwp['firewall_policy']['id'])
req.get_response(self.ext_api)
# shuffle the rules, add more rules
fw_rule_ids = [fr[1]['firewall_rule']['id'],
fr[3]['firewall_rule']['id'],
fr[2]['firewall_rule']['id'],
fr[0]['firewall_rule']['id']]
attrs['firewall_rules'] = fw_rule_ids
data = {'firewall_policy':
{'firewall_rules': fw_rule_ids}}
req = self.new_update_request('firewall_policies', data,
fwp['firewall_policy']['id'])
res = self.deserialize(self.fmt,
req.get_response(self.ext_api))
rules = []
for rule_id in fw_rule_ids:
req = self.new_show_request('firewall_rules',
rule_id,
fmt=self.fmt)
res = self.deserialize(self.fmt,
req.get_response(self.ext_api))
rules.append(res['firewall_rule'])
self.assertEqual(1, rules[0]['position'])
self.assertEqual(fr[1]['firewall_rule']['id'], rules[0]['id'])
self.assertEqual(2, rules[1]['position'])
self.assertEqual(fr[3]['firewall_rule']['id'], rules[1]['id'])
self.assertEqual(3, rules[2]['position'])
self.assertEqual(fr[2]['firewall_rule']['id'], rules[2]['id'])
self.assertEqual(4, rules[3]['position'])
self.assertEqual(fr[0]['firewall_rule']['id'], rules[3]['id'])
def test_update_firewall_policy_with_non_existing_rule(self):
attrs = self._get_test_firewall_policy_attrs()
with self.firewall_rule(name='fwr1') as fwr1, \
self.firewall_rule(name='fwr2') as fwr2:
fr = [fwr1, fwr2]
with self.firewall_policy() as fwp:
fw_rule_ids = [r['firewall_rule']['id'] for r in fr]
# appending non-existent rule
fw_rule_ids.append(uuidutils.generate_uuid())
data = {'firewall_policy':
{'firewall_rules': fw_rule_ids}}
req = self.new_update_request('firewall_policies', data,
fwp['firewall_policy']['id'])
res = req.get_response(self.ext_api)
# check that the firewall_rule was not found
self.assertEqual(404, res.status_int)
# check if none of the rules got added to the policy
req = self.new_show_request('firewall_policies',
fwp['firewall_policy']['id'],
fmt=self.fmt)
res = self.deserialize(self.fmt,
req.get_response(self.ext_api))
for k, v in six.iteritems(attrs):
self.assertEqual(v, res['firewall_policy'][k])
def test_update_shared_firewall_policy_with_unshared_rule(self):
with self.firewall_rule(name='fwr1', shared=False) as fr:
with self.firewall_policy() as fwp:
fw_rule_ids = [fr['firewall_rule']['id']]
# update shared policy with unshared rule
data = {'firewall_policy':
{'firewall_rules': fw_rule_ids}}
req = self.new_update_request('firewall_policies', data,
fwp['firewall_policy']['id'])
res = req.get_response(self.ext_api)
self.assertEqual(webob.exc.HTTPConflict.code, res.status_int)
def test_update_firewall_policy_with_shared_attr_unshared_rule(self):
with self.firewall_rule(name='fwr1', shared=False) as fr:
with self.firewall_policy(shared=False) as fwp:
fw_rule_ids = [fr['firewall_rule']['id']]
# update shared policy with shared attr and unshared rule
data = {'firewall_policy': {'shared': True,
'firewall_rules': fw_rule_ids}}
req = self.new_update_request('firewall_policies', data,
fwp['firewall_policy']['id'])
res = req.get_response(self.ext_api)
self.assertEqual(webob.exc.HTTPConflict.code, res.status_int)
def test_update_firewall_policy_with_shared_attr_exist_unshare_rule(self):
with self.firewall_rule(name='fwr1', shared=False) as fr:
fw_rule_ids = [fr['firewall_rule']['id']]
with self.firewall_policy(shared=False,
firewall_rules=fw_rule_ids) as fwp:
# update policy with shared attr
data = {'firewall_policy': {'shared': True}}
req = self.new_update_request('firewall_policies', data,
fwp['firewall_policy']['id'])
res = req.get_response(self.ext_api)
self.assertEqual(webob.exc.HTTPConflict.code, res.status_int)
def test_update_firewall_policy_assoc_with_other_tenant_firewall(self):
with self.firewall_policy(shared=True, tenant_id='tenant1') as fwp:
fwp_id = fwp['firewall_policy']['id']
with self.firewall(firewall_policy_id=fwp_id):
data = {'firewall_policy': {'shared': False}}
req = self.new_update_request('firewall_policies', data,
fwp['firewall_policy']['id'])
res = req.get_response(self.ext_api)
self.assertEqual(webob.exc.HTTPConflict.code, res.status_int)
def test_delete_firewall_policy(self):
ctx = context.get_admin_context()
with self.firewall_policy(do_delete=False) as fwp:
fwp_id = fwp['firewall_policy']['id']
req = self.new_delete_request('firewall_policies', fwp_id)
res = req.get_response(self.ext_api)
self.assertEqual(204, res.status_int)
self.assertRaises(firewall.FirewallPolicyNotFound,
self.plugin.get_firewall_policy,
ctx, fwp_id)
def test_delete_firewall_policy_with_rule(self):
ctx = context.get_admin_context()
attrs = self._get_test_firewall_policy_attrs()
with self.firewall_policy(do_delete=False) as fwp:
fwp_id = fwp['firewall_policy']['id']
with self.firewall_rule(name='fwr1') as fr:
fr_id = fr['firewall_rule']['id']
fw_rule_ids = [fr_id]
attrs['firewall_rules'] = fw_rule_ids
data = {'firewall_policy':
{'firewall_rules': fw_rule_ids}}
req = self.new_update_request('firewall_policies', data,
fwp['firewall_policy']['id'])
req.get_response(self.ext_api)
fw_rule = self.plugin.get_firewall_rule(ctx, fr_id)
self.assertEqual(fwp_id, fw_rule['firewall_policy_id'])
req = self.new_delete_request('firewall_policies', fwp_id)
res = req.get_response(self.ext_api)
self.assertEqual(204, res.status_int)
self.assertRaises(firewall.FirewallPolicyNotFound,
self.plugin.get_firewall_policy,
ctx, fwp_id)
fw_rule = self.plugin.get_firewall_rule(ctx, fr_id)
self.assertIsNone(fw_rule['firewall_policy_id'])
def test_delete_firewall_policy_with_firewall_association(self):
attrs = self._get_test_firewall_attrs()
with self.firewall_policy() as fwp:
fwp_id = fwp['firewall_policy']['id']
attrs['firewall_policy_id'] = fwp_id
with self.firewall(
firewall_policy_id=fwp_id,
admin_state_up=ADMIN_STATE_UP):
req = self.new_delete_request('firewall_policies', fwp_id)
res = req.get_response(self.ext_api)
self.assertEqual(409, res.status_int)
def test_create_firewall_rule(self):
attrs = self._get_test_firewall_rule_attrs()
with self.firewall_rule() as firewall_rule:
for k, v in six.iteritems(attrs):
self.assertEqual(v, firewall_rule['firewall_rule'][k])
attrs['source_port'] = None
attrs['destination_port'] = None
with self.firewall_rule(source_port=None,
destination_port=None) as firewall_rule:
for k, v in six.iteritems(attrs):
self.assertEqual(v, firewall_rule['firewall_rule'][k])
attrs['source_port'] = '10000'
attrs['destination_port'] = '80'
with self.firewall_rule(source_port=10000,
destination_port=80) as firewall_rule:
for k, v in six.iteritems(attrs):
self.assertEqual(v, firewall_rule['firewall_rule'][k])
attrs['source_port'] = '10000'
attrs['destination_port'] = '80'
with self.firewall_rule(source_port='10000',
destination_port='80') as firewall_rule:
for k, v in six.iteritems(attrs):
self.assertEqual(v, firewall_rule['firewall_rule'][k])
def test_create_firewall_src_port_illegal_range(self):
attrs = self._get_test_firewall_rule_attrs()
attrs['source_port'] = '65535:1024'
res = self._create_firewall_rule(self.fmt, **attrs)
self.assertEqual(400, res.status_int)
def test_create_firewall_dest_port_illegal_range(self):
attrs = self._get_test_firewall_rule_attrs()
attrs['destination_port'] = '65535:1024'
res = self._create_firewall_rule(self.fmt, **attrs)
self.assertEqual(400, res.status_int)
def test_create_firewall_rule_icmp_with_port(self):
attrs = self._get_test_firewall_rule_attrs()
attrs['protocol'] = 'icmp'
res = self._create_firewall_rule(self.fmt, **attrs)
self.assertEqual(400, res.status_int)
def test_create_firewall_rule_icmp_without_port(self):
attrs = self._get_test_firewall_rule_attrs()
attrs['protocol'] = 'icmp'
attrs['source_port'] = None
attrs['destination_port'] = None
with self.firewall_rule(source_port=None,
destination_port=None,
protocol='icmp') as firewall_rule:
for k, v in six.iteritems(attrs):
self.assertEqual(v, firewall_rule['firewall_rule'][k])
def test_create_firewall_without_source(self):
attrs = self._get_test_firewall_rule_attrs()
attrs['source_ip_address'] = None
res = self._create_firewall_rule(self.fmt, **attrs)
self.assertEqual(201, res.status_int)
def test_create_firewall_rule_without_destination(self):
attrs = self._get_test_firewall_rule_attrs()
attrs['destination_ip_address'] = None
res = self._create_firewall_rule(self.fmt, **attrs)
self.assertEqual(201, res.status_int)
def test_create_firewall_rule_without_protocol_with_dport(self):
attrs = self._get_test_firewall_rule_attrs()
attrs['protocol'] = None
attrs['source_port'] = None
res = self._create_firewall_rule(self.fmt, **attrs)
self.assertEqual(400, res.status_int)
def test_create_firewall_rule_without_protocol_with_sport(self):
attrs = self._get_test_firewall_rule_attrs()
attrs['protocol'] = None
attrs['destination_port'] = None
res = self._create_firewall_rule(self.fmt, **attrs)
self.assertEqual(400, res.status_int)
def test_show_firewall_rule_with_fw_policy_not_associated(self):
attrs = self._get_test_firewall_rule_attrs()
with self.firewall_rule() as fw_rule:
req = self.new_show_request('firewall_rules',
fw_rule['firewall_rule']['id'],
fmt=self.fmt)
res = self.deserialize(self.fmt,
req.get_response(self.ext_api))
for k, v in six.iteritems(attrs):
self.assertEqual(v, res['firewall_rule'][k])
def test_show_firewall_rule_with_fw_policy_associated(self):
attrs = self._get_test_firewall_rule_attrs()
with self.firewall_rule() as fw_rule:
with self.firewall_policy() as fwp:
fwp_id = fwp['firewall_policy']['id']
attrs['firewall_policy_id'] = fwp_id
data = {'firewall_policy':
{'firewall_rules':
[fw_rule['firewall_rule']['id']]}}
req = self.new_update_request('firewall_policies', data,
fwp['firewall_policy']['id'])
req.get_response(self.ext_api)
req = self.new_show_request('firewall_rules',
fw_rule['firewall_rule']['id'],
fmt=self.fmt)
res = self.deserialize(self.fmt,
req.get_response(self.ext_api))
for k, v in six.iteritems(attrs):
self.assertEqual(v, res['firewall_rule'][k])
def test_create_firewall_rule_with_ipv6_addrs_and_wrong_ip_version(self):
attrs = self._get_test_firewall_rule_attrs()
attrs['source_ip_address'] = '::/0'
attrs['destination_ip_address'] = '2001:db8:3::/64'
attrs['ip_version'] = 4
res = self._create_firewall_rule(self.fmt, **attrs)
self.assertEqual(400, res.status_int)
attrs = self._get_test_firewall_rule_attrs()
attrs['source_ip_address'] = None
attrs['destination_ip_address'] = '2001:db8:3::/64'
attrs['ip_version'] = 4
res = self._create_firewall_rule(self.fmt, **attrs)
self.assertEqual(400, res.status_int)
attrs = self._get_test_firewall_rule_attrs()
attrs['source_ip_address'] = '::/0'
attrs['destination_ip_address'] = None
attrs['ip_version'] = 4
res = self._create_firewall_rule(self.fmt, **attrs)
self.assertEqual(400, res.status_int)
def test_list_firewall_rules(self):
with self.firewall_rule(name='fwr1') as fwr1, \
self.firewall_rule(name='fwr2') as fwr2, \
self.firewall_rule(name='fwr3') as fwr3:
fr = [fwr1, fwr2, fwr3]
query_params = 'protocol=tcp'
self._test_list_resources('firewall_rule', fr,
query_params=query_params)
def test_update_firewall_rule(self):
name = "new_firewall_rule1"
attrs = self._get_test_firewall_rule_attrs(name)
attrs['source_port'] = '10:20'
attrs['destination_port'] = '30:40'
with self.firewall_rule() as fwr:
data = {'firewall_rule': {'name': name,
'source_port': '10:20',
'destination_port': '30:40'}}
req = self.new_update_request('firewall_rules', data,
fwr['firewall_rule']['id'])
res = self.deserialize(self.fmt,
req.get_response(self.ext_api))
for k, v in six.iteritems(attrs):
self.assertEqual(v, res['firewall_rule'][k])
attrs['source_port'] = '10000'
attrs['destination_port'] = '80'
with self.firewall_rule() as fwr:
data = {'firewall_rule': {'name': name,
'source_port': 10000,
'destination_port': 80}}
req = self.new_update_request('firewall_rules', data,
fwr['firewall_rule']['id'])
res = self.deserialize(self.fmt,
req.get_response(self.ext_api))
for k, v in six.iteritems(attrs):
self.assertEqual(v, res['firewall_rule'][k])
attrs['source_port'] = '10000'
attrs['destination_port'] = '80'
with self.firewall_rule() as fwr:
data = {'firewall_rule': {'name': name,
'source_port': '10000',
'destination_port': '80'}}
req = self.new_update_request('firewall_rules', data,
fwr['firewall_rule']['id'])
res = self.deserialize(self.fmt,
req.get_response(self.ext_api))
for k, v in six.iteritems(attrs):
self.assertEqual(v, res['firewall_rule'][k])
attrs['source_port'] = None
attrs['destination_port'] = None
with self.firewall_rule() as fwr:
data = {'firewall_rule': {'name': name,
'source_port': None,
'destination_port': None}}
req = self.new_update_request('firewall_rules', data,
fwr['firewall_rule']['id'])
res = self.deserialize(self.fmt,
req.get_response(self.ext_api))
for k, v in six.iteritems(attrs):
self.assertEqual(v, res['firewall_rule'][k])
def test_update_firewall_rule_with_port_and_no_proto(self):
with self.firewall_rule() as fwr:
data = {'firewall_rule': {'protocol': None,
'destination_port': 80}}
req = self.new_update_request('firewall_rules', data,
fwr['firewall_rule']['id'])
res = req.get_response(self.ext_api)
self.assertEqual(400, res.status_int)
def test_update_firewall_rule_without_ports_and_no_proto(self):
with self.firewall_rule() as fwr:
data = {'firewall_rule': {'protocol': None,
'destination_port': None,
'source_port': None}}
req = self.new_update_request('firewall_rules', data,
fwr['firewall_rule']['id'])
res = req.get_response(self.ext_api)
self.assertEqual(200, res.status_int)
def test_update_firewall_rule_with_port(self):
with self.firewall_rule(source_port=None,
destination_port=None,
protocol=None) as fwr:
data = {'firewall_rule': {'destination_port': 80}}
req = self.new_update_request('firewall_rules', data,
fwr['firewall_rule']['id'])
res = req.get_response(self.ext_api)
self.assertEqual(400, res.status_int)
def test_update_firewall_rule_with_port_illegal_range(self):
with self.firewall_rule() as fwr:
data = {'firewall_rule': {'destination_port': '65535:1024'}}
req = self.new_update_request('firewall_rules', data,
fwr['firewall_rule']['id'])
res = req.get_response(self.ext_api)
self.assertEqual(400, res.status_int)
def test_update_firewall_rule_with_port_and_protocol(self):
with self.firewall_rule(source_port=None,
destination_port=None,
protocol=None) as fwr:
data = {'firewall_rule': {'destination_port': 80,
'protocol': 'tcp'}}
req = self.new_update_request('firewall_rules', data,
fwr['firewall_rule']['id'])
res = req.get_response(self.ext_api)
self.assertEqual(200, res.status_int)
def test_update_firewall_rule_with_policy_associated(self):
name = "new_firewall_rule1"
attrs = self._get_test_firewall_rule_attrs(name)
with self.firewall_rule() as fwr:
with self.firewall_policy() as fwp:
fwp_id = fwp['firewall_policy']['id']
attrs['firewall_policy_id'] = fwp_id
fwr_id = fwr['firewall_rule']['id']
data = {'firewall_policy': {'firewall_rules': [fwr_id]}}
req = self.new_update_request('firewall_policies', data,
fwp['firewall_policy']['id'])
req.get_response(self.ext_api)
data = {'firewall_rule': {'name': name}}
req = self.new_update_request('firewall_rules', data,
fwr['firewall_rule']['id'])
res = self.deserialize(self.fmt,
req.get_response(self.ext_api))
attrs['firewall_policy_id'] = fwp_id
for k, v in six.iteritems(attrs):
self.assertEqual(v, res['firewall_rule'][k])
req = self.new_show_request('firewall_policies',
fwp['firewall_policy']['id'],
fmt=self.fmt)
res = self.deserialize(self.fmt,
req.get_response(self.ext_api))
self.assertEqual(
[fwr_id],
res['firewall_policy']['firewall_rules'])
self.assertFalse(res['firewall_policy']['audited'])
def test_update_firewall_rule_associated_with_other_tenant_policy(self):
with self.firewall_rule(shared=True, tenant_id='tenant1') as fwr:
fwr_id = [fwr['firewall_rule']['id']]
with self.firewall_policy(shared=False,
firewall_rules=fwr_id):
data = {'firewall_rule': {'shared': False}}
req = self.new_update_request('firewall_rules', data,
fwr['firewall_rule']['id'])
res = req.get_response(self.ext_api)
self.assertEqual(webob.exc.HTTPConflict.code, res.status_int)
def test_delete_firewall_rule(self):
ctx = context.get_admin_context()
with self.firewall_rule(do_delete=False) as fwr:
fwr_id = fwr['firewall_rule']['id']
req = self.new_delete_request('firewall_rules', fwr_id)
res = req.get_response(self.ext_api)
self.assertEqual(204, res.status_int)
self.assertRaises(firewall.FirewallRuleNotFound,
self.plugin.get_firewall_rule,
ctx, fwr_id)
def test_delete_firewall_rule_with_policy_associated(self):
attrs = self._get_test_firewall_rule_attrs()
with self.firewall_rule() as fwr:
with self.firewall_policy() as fwp:
fwp_id = fwp['firewall_policy']['id']
attrs['firewall_policy_id'] = fwp_id
fwr_id = fwr['firewall_rule']['id']
data = {'firewall_policy': {'firewall_rules': [fwr_id]}}
req = self.new_update_request('firewall_policies', data,
fwp['firewall_policy']['id'])
req.get_response(self.ext_api)
req = self.new_delete_request('firewall_rules', fwr_id)
res = req.get_response(self.ext_api)
self.assertEqual(409, res.status_int)
def _test_create_firewall(self, attrs):
with self.firewall_policy() as fwp:
fwp_id = fwp['firewall_policy']['id']
attrs['firewall_policy_id'] = fwp_id
with self.firewall(
name=attrs['name'],
firewall_policy_id=fwp_id,
admin_state_up=ADMIN_STATE_UP
) as firewall:
for k, v in six.iteritems(attrs):
self.assertEqual(v, firewall['firewall'][k])
def test_create_firewall(self):
attrs = self._get_test_firewall_attrs("firewall1")
self._test_create_firewall(attrs)
def test_create_firewall_with_dvr(self):
cfg.CONF.set_override('router_distributed', True)
attrs = self._get_test_firewall_attrs("firewall1", "CREATED")
self._test_create_firewall(attrs)
def test_create_firewall_with_fwp_does_not_exist(self):
fmt = self.fmt
fw_name = "firewall1"
description = "my_firewall1"
not_found_fwp_id = uuidutils.generate_uuid()
self._create_firewall(fmt, fw_name,
description, not_found_fwp_id,
ADMIN_STATE_UP,
expected_res_status=404)
def test_create_firewall_with_fwp_not_found_on_different_tenant(self):
fmt = self.fmt
fw_name = "firewall1"
description = "my_firewall1"
with self.firewall_policy(shared=False, tenant_id='tenant2') as fwp:
fwp_id = fwp['firewall_policy']['id']
ctx = context.Context('not_admin', 'tenant1')
self._create_firewall(fmt, fw_name,
description, fwp_id,
context=ctx,
expected_res_status=404)
def test_create_firewall_with_admin_and_fwp_different_tenant(self):
fmt = self.fmt
fw_name = "firewall1"
description = "my_firewall1"
with self.firewall_policy(shared=False, tenant_id='tenant2') as fwp:
fwp_id = fwp['firewall_policy']['id']
ctx = context.get_admin_context()
self._create_firewall(fmt, fw_name,
description, fwp_id,
tenant_id="admin-tenant",
context=ctx,
expected_res_status=409)
def test_create_firewall_with_admin_and_fwp_is_shared(self):
fw_name = "fw_with_shared_fwp"
with self.firewall_policy(tenant_id="tenantX") as fwp:
fwp_id = fwp['firewall_policy']['id']
ctx = context.get_admin_context()
target_tenant = 'tenant1'
with self.firewall(name=fw_name, firewall_policy_id=fwp_id,
tenant_id=target_tenant, context=ctx,
admin_state_up=ADMIN_STATE_UP) as fw:
self.assertEqual(target_tenant, fw['firewall']['tenant_id'])
def test_show_firewall(self):
name = "firewall1"
attrs = self._get_test_firewall_attrs(name)
with self.firewall_policy() as fwp:
fwp_id = fwp['firewall_policy']['id']
attrs['firewall_policy_id'] = fwp_id
with self.firewall(
name=name,
firewall_policy_id=fwp_id,
admin_state_up=ADMIN_STATE_UP) as firewall:
req = self.new_show_request('firewalls',
firewall['firewall']['id'],
fmt=self.fmt)
res = self.deserialize(self.fmt,
req.get_response(self.ext_api))
for k, v in six.iteritems(attrs):
self.assertEqual(v, res['firewall'][k])
def test_list_firewalls(self):
with self.firewall_policy() as fwp:
fwp_id = fwp['firewall_policy']['id']
with self.firewall(name='fw1', tenant_id='tenant1',
firewall_policy_id=fwp_id,
description='fw') as fw1, \
self.firewall(name='fw2', tenant_id='tenant2',
firewall_policy_id=fwp_id,
description='fw') as fw2, \
self.firewall(name='fw3', tenant_id='tenant3',
firewall_policy_id=fwp_id,
description='fw') as fw3:
fwalls = [fw1, fw2, fw3]
self._test_list_resources('firewall', fwalls,
query_params='description=fw')
def test_update_firewall(self):
name = "new_firewall1"
attrs = self._get_test_firewall_attrs(name)
with self.firewall_policy() as fwp:
fwp_id = fwp['firewall_policy']['id']
attrs['firewall_policy_id'] = fwp_id
with self.firewall(
firewall_policy_id=fwp_id,
admin_state_up=ADMIN_STATE_UP) as firewall:
data = {'firewall': {'name': name}}
req = self.new_update_request('firewalls', data,
firewall['firewall']['id'])
res = self.deserialize(self.fmt,
req.get_response(self.ext_api))
for k, v in six.iteritems(attrs):
self.assertEqual(v, res['firewall'][k])
def test_update_firewall_with_fwp(self):
ctx = context.Context('not_admin', 'tenant1')
with self.firewall_policy() as fwp1, \
self.firewall_policy(
tenant_id='tenant1', shared=False) as fwp2, \
self.firewall(firewall_policy_id=fwp1['firewall_policy']['id'],
context=ctx) as fw:
fw_id = fw['firewall']['id']
fwp2_id = fwp2['firewall_policy']['id']
data = {'firewall': {'firewall_policy_id': fwp2_id}}
req = self.new_update_request('firewalls', data, fw_id,
context=ctx)
res = req.get_response(self.ext_api)
self.assertEqual(200, res.status_int)
def test_update_firewall_with_shared_fwp(self):
ctx = context.Context('not_admin', 'tenant1')
with self.firewall_policy() as fwp1, \
self.firewall_policy(tenant_id='tenant2') as fwp2, \
self.firewall(firewall_policy_id=fwp1['firewall_policy']['id'],
context=ctx) as fw:
fw_id = fw['firewall']['id']
fwp2_id = fwp2['firewall_policy']['id']
data = {'firewall': {'firewall_policy_id': fwp2_id}}
req = self.new_update_request('firewalls', data, fw_id,
context=ctx)
res = req.get_response(self.ext_api)
self.assertEqual(200, res.status_int)
def test_update_firewall_with_admin_and_fwp_different_tenant(self):
ctx = context.get_admin_context()
with self.firewall_policy() as fwp1, \
self.firewall_policy(
tenant_id='tenant2', shared=False) as fwp2, \
self.firewall(firewall_policy_id=fwp1['firewall_policy']['id'],
context=ctx) as fw:
fw_id = fw['firewall']['id']
fwp2_id = fwp2['firewall_policy']['id']
data = {'firewall': {'firewall_policy_id': fwp2_id}}
req = self.new_update_request('firewalls', data, fw_id,
context=ctx)
res = req.get_response(self.ext_api)
self.assertEqual(409, res.status_int)
def test_update_firewall_fwp_not_found_on_different_tenant(self):
with self.firewall_policy(name='fwp1', tenant_id='tenant1',
do_delete=False) as fwp1, \
self.firewall_policy(name='fwp2', shared=False,
tenant_id='tenant2') as fwp2:
fwps = [fwp1, fwp2]
# create firewall using fwp1 exists the same tenant.
fwp1_id = fwps[0]['firewall_policy']['id']
fwp2_id = fwps[1]['firewall_policy']['id']
ctx = context.Context('not_admin', 'tenant1')
with self.firewall(firewall_policy_id=fwp1_id,
context=ctx) as firewall:
fw_id = firewall['firewall']['id']
fw_db = self.plugin._get_firewall(ctx, fw_id)
fw_db['status'] = constants.ACTIVE
# update firewall from fwp1 to fwp2(different tenant)
data = {'firewall': {'firewall_policy_id': fwp2_id}}
req = self.new_update_request('firewalls', data, fw_id,
context=ctx)
res = req.get_response(self.ext_api)
self.assertEqual(404, res.status_int)
def test_delete_firewall(self):
ctx = context.get_admin_context()
with self.firewall_policy() as fwp:
fwp_id = fwp['firewall_policy']['id']
with self.firewall(firewall_policy_id=fwp_id,
do_delete=False) as fw:
fw_id = fw['firewall']['id']
req = self.new_delete_request('firewalls', fw_id)
res = req.get_response(self.ext_api)
self.assertEqual(204, res.status_int)
self.assertRaises(firewall.FirewallNotFound,
self.plugin.get_firewall,
ctx, fw_id)
def test_insert_rule_in_policy_with_prior_rules_added_via_update(self):
attrs = self._get_test_firewall_policy_attrs()
attrs['audited'] = False
attrs['firewall_list'] = []
with self.firewall_rule(name='fwr1') as fwr1, \
self.firewall_rule(name='fwr2') as fwr2, \
self.firewall_rule(name='fwr3') as fwr3:
frs = [fwr1, fwr2, fwr3]
fr1 = frs[0:2]
fwr3 = frs[2]
with self.firewall_policy() as fwp:
fwp_id = fwp['firewall_policy']['id']
attrs['id'] = fwp_id
fw_rule_ids = [r['firewall_rule']['id'] for r in fr1]
attrs['firewall_rules'] = fw_rule_ids[:]
data = {'firewall_policy':
{'firewall_rules': fw_rule_ids}}
req = self.new_update_request('firewall_policies', data,
fwp_id)
req.get_response(self.ext_api)
self._rule_action('insert', fwp_id, fw_rule_ids[0],
insert_before=fw_rule_ids[0],
insert_after=None,
expected_code=webob.exc.HTTPConflict.code,
expected_body=None)
fwr3_id = fwr3['firewall_rule']['id']
attrs['firewall_rules'].insert(0, fwr3_id)
self._rule_action('insert', fwp_id, fwr3_id,
insert_before=fw_rule_ids[0],
insert_after=None,
expected_code=webob.exc.HTTPOk.code,
expected_body=attrs)
def test_insert_rule_in_policy_failures(self):
with self.firewall_rule(name='fwr1') as fr1:
with self.firewall_policy() as fwp:
fwp_id = fwp['firewall_policy']['id']
fr1_id = fr1['firewall_rule']['id']
fw_rule_ids = [fr1_id]
data = {'firewall_policy':
{'firewall_rules': fw_rule_ids}}
req = self.new_update_request('firewall_policies', data,
fwp_id)
req.get_response(self.ext_api)
# test inserting with empty request body
self._rule_action('insert', fwp_id, '123',
expected_code=webob.exc.HTTPBadRequest.code,
expected_body=None, body_data={})
# test inserting when firewall_rule_id is missing in
# request body
insert_data = {'insert_before': '123',
'insert_after': '456'}
self._rule_action('insert', fwp_id, '123',
expected_code=webob.exc.HTTPBadRequest.code,
expected_body=None,
body_data=insert_data)
# test inserting when firewall_rule_id is None
insert_data = {'firewall_rule_id': None,
'insert_before': '123',
'insert_after': '456'}
self._rule_action('insert', fwp_id, '123',
expected_code=webob.exc.HTTPNotFound.code,
expected_body=None,
body_data=insert_data)
# test inserting when firewall_policy_id is incorrect
self._rule_action('insert', '123', fr1_id,
expected_code=webob.exc.HTTPNotFound.code,
expected_body=None)
# test inserting when firewall_policy_id is None
self._rule_action('insert', None, fr1_id,
expected_code=webob.exc.HTTPBadRequest.code,
expected_body=None)
def test_insert_rule_for_previously_associated_rule(self):
with self.firewall_rule() as fwr:
fwr_id = fwr['firewall_rule']['id']
fw_rule_ids = [fwr_id]
with self.firewall_policy(firewall_rules=fw_rule_ids):
with self.firewall_policy(name='firewall_policy2') as fwp:
fwp_id = fwp['firewall_policy']['id']
insert_data = {'firewall_rule_id': fwr_id}
self._rule_action(
'insert', fwp_id, fwr_id, insert_before=None,
insert_after=None,
expected_code=webob.exc.HTTPConflict.code,
expected_body=None, body_data=insert_data)
def test_insert_rule_for_prev_associated_ref_rule(self):
with self.firewall_rule(name='fwr0') as fwr0, \
self.firewall_rule(name='fwr1') as fwr1:
fwr = [fwr0, fwr1]
fwr0_id = fwr[0]['firewall_rule']['id']
fwr1_id = fwr[1]['firewall_rule']['id']
with self.firewall_policy(name='fwp0') as fwp0, \
self.firewall_policy(name='fwp1',
firewall_rules=[fwr1_id]) as fwp1:
fwp = [fwp0, fwp1]
fwp0_id = fwp[0]['firewall_policy']['id']
# test inserting before a rule which
# is associated with different policy
self._rule_action('insert', fwp0_id, fwr0_id,
insert_before=fwr1_id,
expected_code=webob.exc.HTTPBadRequest.code,
expected_body=None)
# test inserting after a rule which
# is associated with different policy
self._rule_action('insert', fwp0_id, fwr0_id,
insert_after=fwr1_id,
expected_code=webob.exc.HTTPBadRequest.code,
expected_body=None)
def test_insert_rule_for_policy_of_other_tenant(self):
with self.firewall_rule(tenant_id='tenant-2', shared=False) as fwr:
fwr_id = fwr['firewall_rule']['id']
with self.firewall_policy(name='firewall_policy') as fwp:
fwp_id = fwp['firewall_policy']['id']
insert_data = {'firewall_rule_id': fwr_id}
self._rule_action(
'insert', fwp_id, fwr_id, insert_before=None,
insert_after=None,
expected_code=webob.exc.HTTPConflict.code,
expected_body=None, body_data=insert_data)
def test_insert_rule_in_policy(self):
attrs = self._get_test_firewall_policy_attrs()
attrs['audited'] = False
attrs['firewall_list'] = []
with self.firewall_rule(name='fwr0') as fwr0, \
self.firewall_rule(name='fwr1') as fwr1, \
self.firewall_rule(name='fwr2') as fwr2, \
self.firewall_rule(name='fwr3') as fwr3, \
self.firewall_rule(name='fwr4') as fwr4, \
self.firewall_rule(name='fwr5') as fwr5, \
self.firewall_rule(name='fwr6') as fwr6:
fwr = [fwr0, fwr1, fwr2, fwr3, fwr4, fwr5, fwr6]
with self.firewall_policy() as fwp:
fwp_id = fwp['firewall_policy']['id']
attrs['id'] = fwp_id
# test insert when rule list is empty
fwr0_id = fwr[0]['firewall_rule']['id']
attrs['firewall_rules'].insert(0, fwr0_id)
self._rule_action('insert', fwp_id, fwr0_id,
insert_before=None,
insert_after=None,
expected_code=webob.exc.HTTPOk.code,
expected_body=attrs)
# test insert at top of rule list, insert_before and
# insert_after not provided
fwr1_id = fwr[1]['firewall_rule']['id']
attrs['firewall_rules'].insert(0, fwr1_id)
insert_data = {'firewall_rule_id': fwr1_id}
self._rule_action('insert', fwp_id, fwr0_id,
expected_code=webob.exc.HTTPOk.code,
expected_body=attrs, body_data=insert_data)
# test insert at top of list above existing rule
fwr2_id = fwr[2]['firewall_rule']['id']
attrs['firewall_rules'].insert(0, fwr2_id)
self._rule_action('insert', fwp_id, fwr2_id,
insert_before=fwr1_id,
insert_after=None,
expected_code=webob.exc.HTTPOk.code,
expected_body=attrs)
# test insert at bottom of list
fwr3_id = fwr[3]['firewall_rule']['id']
attrs['firewall_rules'].append(fwr3_id)
self._rule_action('insert', fwp_id, fwr3_id,
insert_before=None,
insert_after=fwr0_id,
expected_code=webob.exc.HTTPOk.code,
expected_body=attrs)
# test insert in the middle of the list using
# insert_before
fwr4_id = fwr[4]['firewall_rule']['id']
attrs['firewall_rules'].insert(1, fwr4_id)
self._rule_action('insert', fwp_id, fwr4_id,
insert_before=fwr1_id,
insert_after=None,
expected_code=webob.exc.HTTPOk.code,
expected_body=attrs)
# test insert in the middle of the list using
# insert_after
fwr5_id = fwr[5]['firewall_rule']['id']
attrs['firewall_rules'].insert(1, fwr5_id)
self._rule_action('insert', fwp_id, fwr5_id,
insert_before=None,
insert_after=fwr2_id,
expected_code=webob.exc.HTTPOk.code,
expected_body=attrs)
# test insert when both insert_before and
# insert_after are set
fwr6_id = fwr[6]['firewall_rule']['id']
attrs['firewall_rules'].insert(1, fwr6_id)
self._rule_action('insert', fwp_id, fwr6_id,
insert_before=fwr5_id,
insert_after=fwr5_id,
expected_code=webob.exc.HTTPOk.code,
expected_body=attrs)
def test_remove_rule_from_policy(self):
attrs = self._get_test_firewall_policy_attrs()
attrs['audited'] = False
attrs['firewall_list'] = []
with self.firewall_rule(name='fwr1') as fwr1, \
self.firewall_rule(name='fwr2') as fwr2, \
self.firewall_rule(name='fwr3') as fwr3:
fr1 = [fwr1, fwr2, fwr3]
with self.firewall_policy() as fwp:
fwp_id = fwp['firewall_policy']['id']
attrs['id'] = fwp_id
fw_rule_ids = [r['firewall_rule']['id'] for r in fr1]
attrs['firewall_rules'] = fw_rule_ids[:]
data = {'firewall_policy':
{'firewall_rules': fw_rule_ids}}
req = self.new_update_request('firewall_policies', data,
fwp_id)
req.get_response(self.ext_api)
# test removing a rule from a policy that does not exist
self._rule_action('remove', '123', fw_rule_ids[1],
expected_code=webob.exc.HTTPNotFound.code,
expected_body=None)
# test removing a rule in the middle of the list
attrs['firewall_rules'].remove(fw_rule_ids[1])
self._rule_action('remove', fwp_id, fw_rule_ids[1],
expected_body=attrs)
# test removing a rule at the top of the list
attrs['firewall_rules'].remove(fw_rule_ids[0])
self._rule_action('remove', fwp_id, fw_rule_ids[0],
expected_body=attrs)
# test removing remaining rule in the list
attrs['firewall_rules'].remove(fw_rule_ids[2])
self._rule_action('remove', fwp_id, fw_rule_ids[2],
expected_body=attrs)
# test removing rule that is not associated with the policy
self._rule_action('remove', fwp_id, fw_rule_ids[2],
expected_code=webob.exc.HTTPBadRequest.code,
expected_body=None)
def test_remove_rule_from_policy_failures(self):
with self.firewall_rule(name='fwr1') as fr1:
with self.firewall_policy() as fwp:
fwp_id = fwp['firewall_policy']['id']
fw_rule_ids = [fr1['firewall_rule']['id']]
data = {'firewall_policy':
{'firewall_rules': fw_rule_ids}}
req = self.new_update_request('firewall_policies', data,
fwp_id)
req.get_response(self.ext_api)
# test removing rule that does not exist
self._rule_action('remove', fwp_id, '123',
expected_code=webob.exc.HTTPNotFound.code,
expected_body=None)
# test removing rule with bad request
self._rule_action('remove', fwp_id, '123',
expected_code=webob.exc.HTTPBadRequest.code,
expected_body=None, body_data={})
# test removing rule with firewall_rule_id set to None
self._rule_action('remove', fwp_id, '123',
expected_code=webob.exc.HTTPNotFound.code,
expected_body=None,
body_data={'firewall_rule_id': None})
def test_check_router_has_no_firewall_raises(self):
with mock.patch.object(
manager.NeutronManager, 'get_service_plugins') as sp:
fw_plugin = mock.Mock()
sp.return_value = {'FIREWALL': fw_plugin}
fw_plugin.get_firewalls.return_value = [mock.ANY]
kwargs = {
'context': mock.ANY,
'router': {'id': 'foo_id', 'tenant_id': 'foo_tenant'}
}
self.assertRaises(
l3.RouterInUse,
fdb.migration_callback,
'router', 'before_event', mock.ANY,
**kwargs)
def test_check_router_has_no_firewall_passes(self):
with mock.patch.object(manager.NeutronManager,
'get_service_plugins',
return_value={}):
kwargs = {'context': mock.ANY, 'router': mock.ANY}
self.assertIsNone(fdb.migration_callback(
mock.ANY, mock.ANY, mock.ANY, **kwargs))
def test_show_firewall_rule_by_name(self):
with self.firewall_rule(name='firewall_Rule1') as fw_rule:
res = self._show('firewall_rules',
fw_rule['firewall_rule']['id'])
self.assertEqual('firewall_Rule1', res['firewall_rule']['name'])
def test_show_firewall_policy_by_name(self):
with self.firewall_policy(
name='firewall_Policy1') as fw_policy:
res = self._show('firewall_policies',
fw_policy['firewall_policy']['id'])
self.assertEqual(
'firewall_Policy1', res['firewall_policy']['name'])
def test_show_firewall_by_name(self):
with self.firewall(name='fireWall1') as fw:
res = self._show('firewalls', fw['firewall']['id'])
self.assertEqual('fireWall1', res['firewall']['name'])
neutron-fwaas-8.0.0/neutron_fwaas/tests/unit/db/__init__.py 0000664 0005670 0005671 00000000000 12701407720 025131 0 ustar jenkins jenkins 0000000 0000000 neutron-fwaas-8.0.0/neutron_fwaas/tests/functional/ 0000775 0005670 0005671 00000000000 12701410073 023623 5 ustar jenkins jenkins 0000000 0000000 neutron-fwaas-8.0.0/neutron_fwaas/tests/functional/__init__.py 0000664 0005670 0005671 00000000000 12701407720 025727 0 ustar jenkins jenkins 0000000 0000000 neutron-fwaas-8.0.0/neutron_fwaas/tests/functional/test_fwaas_driver.py 0000664 0005670 0005671 00000002125 12701407720 027715 0 ustar jenkins jenkins 0000000 0000000 # Copyright (c) 2015 Cisco Systems, Inc.
# All Rights Reserved.
#
# 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.
# NOTE: The purpose of this module is to provide a nop test to verify that
# the functional gate is working.
from neutron.tests.functional import base
class TestFWaaSDriver(base.BaseSudoTestCase):
"""Test the iptables implementation of the FWaaS driver."""
# NOTE: Tests may be added/removed/changed, when this is fleshed out
# in future commits.
def test_status_reporting(self):
"""Test status reported correctly to agent."""
pass
neutron-fwaas-8.0.0/neutron_fwaas/opts.py 0000664 0005670 0005671 00000001561 12701407720 021666 0 ustar jenkins jenkins 0000000 0000000 # 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.
import neutron_fwaas.services.firewall.agents.firewall_agent_api
def list_agent_opts():
return [
('fwaas',
neutron_fwaas.services.firewall.agents.firewall_agent_api.FWaaSOpts)
]
def list_opts():
return [
('quotas',
neutron_fwaas.extensions.firewall.firewall_quota_opts)
]
neutron-fwaas-8.0.0/neutron_fwaas/__init__.py 0000664 0005670 0005671 00000001363 12701407720 022440 0 ustar jenkins jenkins 0000000 0000000 # Copyright 2011 OpenStack Foundation
# All Rights Reserved.
#
# 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.
import gettext
import six
if six.PY2:
gettext.install('neutron', unicode=1)
else:
gettext.install('neutron')
neutron-fwaas-8.0.0/neutron_fwaas/services/ 0000775 0005670 0005671 00000000000 12701410073 022142 5 ustar jenkins jenkins 0000000 0000000 neutron-fwaas-8.0.0/neutron_fwaas/services/firewall/ 0000775 0005670 0005671 00000000000 12701410073 023747 5 ustar jenkins jenkins 0000000 0000000 neutron-fwaas-8.0.0/neutron_fwaas/services/firewall/__init__.py 0000664 0005670 0005671 00000000000 12701407720 026053 0 ustar jenkins jenkins 0000000 0000000 neutron-fwaas-8.0.0/neutron_fwaas/services/firewall/plugins/ 0000775 0005670 0005671 00000000000 12701410073 025430 5 ustar jenkins jenkins 0000000 0000000 neutron-fwaas-8.0.0/neutron_fwaas/services/firewall/plugins/cisco/ 0000775 0005670 0005671 00000000000 12701410073 026530 5 ustar jenkins jenkins 0000000 0000000 neutron-fwaas-8.0.0/neutron_fwaas/services/firewall/plugins/cisco/__init__.py 0000664 0005670 0005671 00000000000 12701407720 030634 0 ustar jenkins jenkins 0000000 0000000 neutron-fwaas-8.0.0/neutron_fwaas/services/firewall/plugins/cisco/cisco_fwaas_plugin.py 0000664 0005670 0005671 00000037270 12701407720 032757 0 ustar jenkins jenkins 0000000 0000000 # Copyright 2015 Cisco Systems, Inc. All rights reserved.
#
# 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.
#
from neutron.api.v2 import attributes as attr
from neutron.common import rpc as n_rpc
from neutron import context as neutron_context
from neutron import manager
from neutron.plugins.common import constants as const
from neutron_lib import constants as l3_const
from oslo_config import cfg
from oslo_log import helpers as log_helpers
from oslo_log import log as logging
import oslo_messaging
from neutron_fwaas._i18n import _LW
from neutron_fwaas.db.cisco import cisco_fwaas_db as csrfw_db
import neutron_fwaas.extensions
from neutron_fwaas.extensions.cisco import csr_firewall_insertion as csr_ext
from neutron_fwaas.services.firewall import fwaas_plugin as ref_fw_plugin
LOG = logging.getLogger(__name__)
class FirewallCallbacks(object):
target = oslo_messaging.Target(version='1.0')
def __init__(self, plugin):
super(FirewallCallbacks, self).__init__()
self.plugin = plugin
@log_helpers.log_method_call
def set_firewall_status(self, context, firewall_id, status,
status_data=None, **kwargs):
"""Agent uses this to set a firewall's status."""
with context.session.begin(subtransactions=True):
fw_db = self.plugin._get_firewall(context, firewall_id)
# ignore changing status if firewall expects to be deleted
# That case means that while some pending operation has been
# performed on the backend, neutron server received delete request
# and changed firewall status to const.PENDING_DELETE
if status == const.ERROR:
fw_db.status = const.ERROR
return False
if fw_db.status == const.PENDING_DELETE:
LOG.debug("Firewall %(fw_id)s in PENDING_DELETE state, "
"not changing to %(status)s",
{'fw_id': firewall_id, 'status': status})
return False
if status in (const.ACTIVE, const.INACTIVE):
fw_db.status = status
csrfw = self.plugin.lookup_firewall_csr_association(context,
firewall_id)
_fw = {'id': csrfw['fw_id'], 'port_id': csrfw['port_id'],
'direction': csrfw['direction'],
'acl_id': status_data['acl_id']}
self.plugin.update_firewall_csr_association(context,
firewall_id, _fw)
else:
fw_db.status = const.ERROR
@log_helpers.log_method_call
def firewall_deleted(self, context, firewall_id, **kwargs):
"""Agent uses this to indicate firewall is deleted."""
with context.session.begin(subtransactions=True):
fw_db = self.plugin._get_firewall(context, firewall_id)
# allow to delete firewalls in ERROR state
if fw_db.status in (const.PENDING_DELETE, const.ERROR):
self.plugin.delete_db_firewall_object(context, firewall_id)
return True
LOG.warning(_LW('Firewall %(fw)s unexpectedly deleted by agent, '
'status was %(status)s'),
{'fw': firewall_id, 'status': fw_db.status})
fw_db.status = const.ERROR
return False
@log_helpers.log_method_call
def get_firewalls_for_tenant(self, context, **kwargs):
"""Agent uses this to get all firewalls and rules for a tenant."""
fw_list = []
for fw in self.plugin.get_firewalls(context):
fw_with_rules = (
self.plugin._make_firewall_dict_with_rules(context, fw['id']))
csrfw = self.plugin.lookup_firewall_csr_association(context,
fw['id'])
router_id = csrfw['router_id']
fw_with_rules['vendor_ext'] = self.plugin._get_hosting_info(
context, csrfw['port_id'], router_id, csrfw['direction'])
fw_with_rules['vendor_ext']['acl_id'] = csrfw['acl_id']
fw_list.append(fw_with_rules)
return fw_list
@log_helpers.log_method_call
def get_firewalls_for_tenant_without_rules(self, context, **kwargs):
"""Agent uses this to get all firewalls for a tenant."""
return [fw for fw in self.plugin.get_firewalls(context)]
@log_helpers.log_method_call
def get_tenants_with_firewalls(self, context, **kwargs):
"""Agent uses this to get all tenants that have firewalls."""
ctx = neutron_context.get_admin_context()
fw_list = self.plugin.get_firewalls(ctx)
return list(set(fw['tenant_id'] for fw in fw_list))
class FirewallAgentApi(object):
"""Plugin side of plugin to agent RPC API."""
def __init__(self, topic, host):
self.host = host
target = oslo_messaging.Target(topic=topic, version='1.0')
self.client = n_rpc.get_client(target)
def create_firewall(self, context, firewall):
cctxt = self.client.prepare(fanout=True)
cctxt.cast(context, 'create_firewall', firewall=firewall,
host=self.host)
def update_firewall(self, context, firewall):
cctxt = self.client.prepare(fanout=True)
cctxt.cast(context, 'update_firewall', firewall=firewall,
host=self.host)
def delete_firewall(self, context, firewall):
cctxt = self.client.prepare(fanout=True)
cctxt.cast(context, 'delete_firewall', firewall=firewall,
host=self.host)
class CSRFirewallPlugin(ref_fw_plugin.FirewallPlugin,
csrfw_db.CiscoFirewall_db_mixin):
"""Implementation of the Neutron Firewall Service Plugin.
This class implements the Cisco CSR FWaaS Service Plugin,
inherits from the fwaas ref plugin as no changes are made
to handling fwaas policy and rules. The CRUD methods are
overridden to provide for the specific implementation. The
basic fwaas db is managed thru the firewall_db.Firewall_db_mixin.
The backend specific associations are captured in the new table,
csrfw_db.CiscoFirewall_db_mixin.
"""
supported_extension_aliases = ["fwaas", "csrfirewallinsertion"]
def __init__(self):
"""Do the initialization for the firewall service plugin here."""
ext_path = neutron_fwaas.extensions.__path__[0] + '/cisco'
if ext_path not in cfg.CONF.api_extensions_path.split(':'):
cfg.CONF.set_override('api_extensions_path',
cfg.CONF.api_extensions_path + ':' + ext_path)
self.endpoints = [FirewallCallbacks(self)]
self.conn = n_rpc.create_connection()
self.conn.create_consumer(
'CISCO_FW_PLUGIN', self.endpoints, fanout=False)
self.conn.consume_in_threads()
self.agent_rpc = FirewallAgentApi(
'CISCO_FW',
cfg.CONF.host
)
def _rpc_update_firewall(self, context, firewall_id):
status_update = {"firewall": {"status": const.PENDING_UPDATE}}
fw = super(ref_fw_plugin.FirewallPlugin, self).update_firewall(
context, firewall_id, status_update)
if fw:
fw_with_rules = (
self._make_firewall_dict_with_rules(context,
firewall_id))
csrfw = self.lookup_firewall_csr_association(context, firewall_id)
fw_with_rules['vendor_ext'] = self._get_hosting_info(context,
csrfw['port_id'], csrfw['router_id'], csrfw['direction'])
fw_with_rules['vendor_ext']['acl_id'] = csrfw['acl_id']
LOG.debug("Update of Rule or policy: fw_with_rules: %s",
fw_with_rules)
self.agent_rpc.update_firewall(context, fw_with_rules)
@log_helpers.log_method_call
def _validate_fw_port_and_get_router_id(self, context, tenant_id, port_id):
# port validation with router plugin
l3_plugin = manager.NeutronManager.get_service_plugins().get(
const.L3_ROUTER_NAT)
ctx = neutron_context.get_admin_context()
routers = l3_plugin.get_routers(ctx)
router_ids = [
router['id']
for router in routers
if router['tenant_id'] == tenant_id]
port_db = self._core_plugin._get_port(context, port_id)
if not (port_db['device_id'] in router_ids and
port_db['device_owner'] == l3_const.DEVICE_OWNER_ROUTER_INTF):
raise csr_ext.InvalidInterfaceForCSRFW(port_id=port_id)
return port_db['device_id']
def _map_csr_device_info_for_agent(self, hosting_device):
return {'host_mngt_ip': hosting_device['management_ip_address'],
'host_usr_nm': hosting_device['credentials']['username'],
'host_usr_pw': hosting_device['credentials']['password']}
def _get_service_insertion_points(self, context, interfaces, port_id,
direction):
insertion_point = dict()
hosting_info = dict()
for interface in interfaces:
if interface['id'] == port_id:
hosting_info = interface['hosting_info']
if not hosting_info:
raise csr_ext.InvalidRouterHostingInfoForCSRFW(port_id=port_id)
insertion_point['port'] = {'id': port_id,
'hosting_info': hosting_info}
insertion_point['direction'] = direction
return [insertion_point]
def _get_hosting_info(self, context, port_id, router_id, direction):
l3_plugin = manager.NeutronManager.get_service_plugins().get(
const.L3_ROUTER_NAT)
ctx = neutron_context.get_admin_context()
routers = l3_plugin.get_sync_data_ext(ctx)
for router in routers:
if router['id'] == router_id:
vendor_ext = self._map_csr_device_info_for_agent(
router['hosting_device'])
vendor_ext['if_list'] = self._get_service_insertion_points(
context, router['_interfaces'], port_id, direction)
return vendor_ext
# TODO(sridar): we may need to raise an excp - check backlogging
@log_helpers.log_method_call
def create_firewall(self, context, firewall):
port_id = firewall['firewall'].pop('port_id', None)
direction = firewall['firewall'].pop('direction', None)
if port_id == attr.ATTR_NOT_SPECIFIED:
LOG.debug("create_firewall() called")
port_id = None
router_id = None
else:
# TODO(sridar): add check to see if the new port-id does not have
# any associated firewall.
router_id = self._validate_fw_port_and_get_router_id(context,
firewall['firewall']['tenant_id'], port_id)
if direction == attr.ATTR_NOT_SPECIFIED:
direction = None
firewall['firewall']['status'] = const.PENDING_CREATE
fw = super(ref_fw_plugin.FirewallPlugin, self).create_firewall(
context, firewall)
fw_with_rules = (
self._make_firewall_dict_with_rules(context, fw['id']))
if not port_id and not direction:
return fw
# Add entry into firewall associations table
_fw = {'id': fw['id'], 'port_id': port_id,
'direction': direction, 'router_id': router_id, 'acl_id': None}
self.add_firewall_csr_association(context, _fw)
if port_id and direction:
fw_with_rules['vendor_ext'] = self._get_hosting_info(context,
port_id, router_id, direction)
fw_with_rules['vendor_ext']['acl_id'] = None
self.agent_rpc.create_firewall(context, fw_with_rules)
return fw
@log_helpers.log_method_call
def update_firewall(self, context, fwid, firewall):
self._ensure_update_firewall(context, fwid)
csrfw = self.lookup_firewall_csr_association(context, fwid)
port_id = firewall['firewall'].pop('port_id', None)
direction = firewall['firewall'].pop('direction', None)
_fw = {'id': fwid}
if port_id:
tenant_id = self.get_firewall(context, fwid)['tenant_id']
router_id = self._validate_fw_port_and_get_router_id(context,
tenant_id, port_id)
if csrfw and csrfw['port_id']:
# TODO(sridar): add check to see if the new port_id does not
# have any associated firewall.
# we only support a different port if associated
# with the same router
if router_id != csrfw['router_id']:
raise csr_ext.InvalidRouterAssociationForCSRFW(
port_id=port_id)
_fw['port_id'] = port_id
_fw['router_id'] = router_id
else:
_fw['port_id'] = csrfw['port_id'] if csrfw else None
_fw['router_id'] = csrfw['router_id'] if csrfw else None
if direction:
_fw['direction'] = direction
else:
_fw['direction'] = csrfw['direction'] if csrfw else None
_fw['acl_id'] = csrfw['acl_id'] if csrfw else None
self.update_firewall_csr_association(context, fwid, _fw)
firewall['firewall']['status'] = const.PENDING_UPDATE
fw = super(ref_fw_plugin.FirewallPlugin, self).update_firewall(
context, fwid, firewall)
fw_with_rules = (
self._make_firewall_dict_with_rules(context, fw['id']))
if _fw['port_id'] and _fw['direction']:
fw_with_rules['vendor_ext'] = self._get_hosting_info(context,
port_id, csrfw['router_id'], direction)
fw_with_rules['vendor_ext']['acl_id'] = csrfw['acl_id']
LOG.debug("CSR Plugin update: fw_with_rules: %s", fw_with_rules)
self.agent_rpc.update_firewall(context, fw_with_rules)
return fw
@log_helpers.log_method_call
def delete_firewall(self, context, fwid):
self._ensure_update_firewall(context, fwid)
status_update = {"firewall": {"status": const.PENDING_DELETE}}
fw = super(ref_fw_plugin.FirewallPlugin, self).update_firewall(
context, fwid, status_update)
# given that we are not in a PENDING_CREATE we should have
# an acl_id - since it is not present something bad has happened
# on the backend and no sense in sending a msg to the agent.
# Clean up ...
csrfw = self.lookup_firewall_csr_association(context, fwid)
if not csrfw or not csrfw['acl_id']:
self.delete_db_firewall_object(context, fwid)
return
fw_with_rules = (
self._make_firewall_dict_with_rules(context, fw['id']))
fw_with_rules['vendor_ext'] = self._get_hosting_info(context,
csrfw['port_id'], csrfw['router_id'], csrfw['direction'])
fw_with_rules['vendor_ext']['acl_id'] = csrfw['acl_id']
self.agent_rpc.delete_firewall(context, fw_with_rules)
@log_helpers.log_method_call
def get_firewall(self, context, fwid, fields=None):
res = super(ref_fw_plugin.FirewallPlugin, self).get_firewall(
context, fwid, fields)
csrfw = self.lookup_firewall_csr_association(context, res['id'])
if not csrfw:
return res
res['port_id'] = csrfw['port_id']
res['direction'] = csrfw['direction']
res['router_id'] = csrfw['router_id']
return res
neutron-fwaas-8.0.0/neutron_fwaas/services/firewall/plugins/__init__.py 0000664 0005670 0005671 00000000000 12701407720 027534 0 ustar jenkins jenkins 0000000 0000000 neutron-fwaas-8.0.0/neutron_fwaas/services/firewall/drivers/ 0000775 0005670 0005671 00000000000 12701410073 025425 5 ustar jenkins jenkins 0000000 0000000 neutron-fwaas-8.0.0/neutron_fwaas/services/firewall/drivers/linux/ 0000775 0005670 0005671 00000000000 12701410073 026564 5 ustar jenkins jenkins 0000000 0000000 neutron-fwaas-8.0.0/neutron_fwaas/services/firewall/drivers/linux/__init__.py 0000664 0005670 0005671 00000000000 12701407720 030670 0 ustar jenkins jenkins 0000000 0000000 neutron-fwaas-8.0.0/neutron_fwaas/services/firewall/drivers/linux/iptables_fwaas.py 0000664 0005670 0005671 00000033315 12701407720 032134 0 ustar jenkins jenkins 0000000 0000000 # Copyright 2013 Dell Inc.
# All Rights Reserved.
#
# 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.
from neutron.agent.linux import iptables_manager
from oslo_log import log as logging
from neutron_fwaas._i18n import _LE
from neutron_fwaas.extensions import firewall as fw_ext
from neutron_fwaas.services.firewall.drivers import fwaas_base
LOG = logging.getLogger(__name__)
FWAAS_DRIVER_NAME = 'Fwaas iptables driver'
FWAAS_DEFAULT_CHAIN = 'fwaas-default-policy'
FWAAS_TO_IPTABLE_ACTION_MAP = {'allow': 'ACCEPT',
'deny': 'DROP',
'reject': 'REJECT'}
INGRESS_DIRECTION = 'ingress'
EGRESS_DIRECTION = 'egress'
CHAIN_NAME_PREFIX = {INGRESS_DIRECTION: 'i',
EGRESS_DIRECTION: 'o'}
""" Firewall rules are applied on internal-interfaces of Neutron router.
The packets ingressing tenant's network will be on the output
direction on internal-interfaces.
"""
IPTABLES_DIR = {INGRESS_DIRECTION: '-o',
EGRESS_DIRECTION: '-i'}
IPV4 = 'ipv4'
IPV6 = 'ipv6'
IP_VER_TAG = {IPV4: 'v4',
IPV6: 'v6'}
INTERNAL_DEV_PREFIX = 'qr-'
SNAT_INT_DEV_PREFIX = 'sg-'
ROUTER_2_FIP_DEV_PREFIX = 'rfp-'
class IptablesFwaasDriver(fwaas_base.FwaasDriverBase):
"""IPTables driver for Firewall As A Service."""
def __init__(self):
LOG.debug("Initializing fwaas iptables driver")
def create_firewall(self, agent_mode, apply_list, firewall):
LOG.debug('Creating firewall %(fw_id)s for tenant %(tid)s',
{'fw_id': firewall['id'], 'tid': firewall['tenant_id']})
try:
if firewall['admin_state_up']:
self._setup_firewall(agent_mode, apply_list, firewall)
else:
self.apply_default_policy(agent_mode, apply_list, firewall)
except (LookupError, RuntimeError):
# catch known library exceptions and raise Fwaas generic exception
LOG.exception(_LE("Failed to create firewall: %s"), firewall['id'])
raise fw_ext.FirewallInternalDriverError(driver=FWAAS_DRIVER_NAME)
def _get_ipt_mgrs_with_if_prefix(self, agent_mode, router_info):
"""Gets the iptables manager along with the if prefix to apply rules.
With DVR we can have differing namespaces depending on which agent
(on Network or Compute node). Also, there is an associated i/f for
each namespace. The iptables on the relevant namespace and matching
i/f are provided. On the Network node we could have both the snat
namespace and a fip so this is provided back as a list - so in that
scenario rules can be applied on both.
"""
if not router_info.router.get('distributed'):
return [{'ipt': router_info.iptables_manager,
'if_prefix': INTERNAL_DEV_PREFIX}]
ipt_mgrs = []
# TODO(sridar): refactor to get strings to a common location.
if agent_mode == 'dvr_snat':
if router_info.snat_iptables_manager:
ipt_mgrs.append({'ipt': router_info.snat_iptables_manager,
'if_prefix': SNAT_INT_DEV_PREFIX})
if router_info.dist_fip_count:
# handle the fip case on n/w or compute node.
ipt_mgrs.append({'ipt': router_info.iptables_manager,
'if_prefix': ROUTER_2_FIP_DEV_PREFIX})
return ipt_mgrs
def delete_firewall(self, agent_mode, apply_list, firewall):
LOG.debug('Deleting firewall %(fw_id)s for tenant %(tid)s',
{'fw_id': firewall['id'], 'tid': firewall['tenant_id']})
fwid = firewall['id']
try:
for router_info in apply_list:
ipt_if_prefix_list = self._get_ipt_mgrs_with_if_prefix(
agent_mode, router_info)
for ipt_if_prefix in ipt_if_prefix_list:
ipt_mgr = ipt_if_prefix['ipt']
self._remove_chains(fwid, ipt_mgr)
self._remove_default_chains(ipt_mgr)
# apply the changes immediately (no defer in firewall path)
ipt_mgr.defer_apply_off()
except (LookupError, RuntimeError):
# catch known library exceptions and raise Fwaas generic exception
LOG.exception(_LE("Failed to delete firewall: %s"), fwid)
raise fw_ext.FirewallInternalDriverError(driver=FWAAS_DRIVER_NAME)
def update_firewall(self, agent_mode, apply_list, firewall):
LOG.debug('Updating firewall %(fw_id)s for tenant %(tid)s',
{'fw_id': firewall['id'], 'tid': firewall['tenant_id']})
try:
if firewall['admin_state_up']:
self._setup_firewall(agent_mode, apply_list, firewall)
else:
self.apply_default_policy(agent_mode, apply_list, firewall)
except (LookupError, RuntimeError):
# catch known library exceptions and raise Fwaas generic exception
LOG.exception(_LE("Failed to update firewall: %s"), firewall['id'])
raise fw_ext.FirewallInternalDriverError(driver=FWAAS_DRIVER_NAME)
def apply_default_policy(self, agent_mode, apply_list, firewall):
LOG.debug('Applying firewall %(fw_id)s for tenant %(tid)s',
{'fw_id': firewall['id'], 'tid': firewall['tenant_id']})
fwid = firewall['id']
try:
for router_info in apply_list:
ipt_if_prefix_list = self._get_ipt_mgrs_with_if_prefix(
agent_mode, router_info)
for ipt_if_prefix in ipt_if_prefix_list:
# the following only updates local memory; no hole in FW
ipt_mgr = ipt_if_prefix['ipt']
self._remove_chains(fwid, ipt_mgr)
self._remove_default_chains(ipt_mgr)
# create default 'DROP ALL' policy chain
self._add_default_policy_chain_v4v6(ipt_mgr)
self._enable_policy_chain(fwid, ipt_if_prefix)
# apply the changes immediately (no defer in firewall path)
ipt_mgr.defer_apply_off()
except (LookupError, RuntimeError):
# catch known library exceptions and raise Fwaas generic exception
LOG.exception(
_LE("Failed to apply default policy on firewall: %s"), fwid)
raise fw_ext.FirewallInternalDriverError(driver=FWAAS_DRIVER_NAME)
def _setup_firewall(self, agent_mode, apply_list, firewall):
fwid = firewall['id']
for router_info in apply_list:
ipt_if_prefix_list = self._get_ipt_mgrs_with_if_prefix(
agent_mode, router_info)
for ipt_if_prefix in ipt_if_prefix_list:
ipt_mgr = ipt_if_prefix['ipt']
# the following only updates local memory; no hole in FW
self._remove_chains(fwid, ipt_mgr)
self._remove_default_chains(ipt_mgr)
# create default 'DROP ALL' policy chain
self._add_default_policy_chain_v4v6(ipt_mgr)
#create chain based on configured policy
self._setup_chains(firewall, ipt_if_prefix)
# apply the changes immediately (no defer in firewall path)
ipt_mgr.defer_apply_off()
def _get_chain_name(self, fwid, ver, direction):
return '%s%s%s' % (CHAIN_NAME_PREFIX[direction],
IP_VER_TAG[ver],
fwid)
def _setup_chains(self, firewall, ipt_if_prefix):
"""Create Fwaas chain using the rules in the policy
"""
fw_rules_list = firewall['firewall_rule_list']
fwid = firewall['id']
ipt_mgr = ipt_if_prefix['ipt']
#default rules for invalid packets and established sessions
invalid_rule = self._drop_invalid_packets_rule()
est_rule = self._allow_established_rule()
for ver in [IPV4, IPV6]:
if ver == IPV4:
table = ipt_mgr.ipv4['filter']
else:
table = ipt_mgr.ipv6['filter']
ichain_name = self._get_chain_name(fwid, ver, INGRESS_DIRECTION)
ochain_name = self._get_chain_name(fwid, ver, EGRESS_DIRECTION)
for name in [ichain_name, ochain_name]:
table.add_chain(name)
table.add_rule(name, invalid_rule)
table.add_rule(name, est_rule)
for rule in fw_rules_list:
if not rule['enabled']:
continue
iptbl_rule = self._convert_fwaas_to_iptables_rule(rule)
if rule['ip_version'] == 4:
ver = IPV4
table = ipt_mgr.ipv4['filter']
else:
ver = IPV6
table = ipt_mgr.ipv6['filter']
ichain_name = self._get_chain_name(fwid, ver, INGRESS_DIRECTION)
ochain_name = self._get_chain_name(fwid, ver, EGRESS_DIRECTION)
table.add_rule(ichain_name, iptbl_rule)
table.add_rule(ochain_name, iptbl_rule)
self._enable_policy_chain(fwid, ipt_if_prefix)
def _remove_default_chains(self, nsid):
"""Remove fwaas default policy chain."""
self._remove_chain_by_name(IPV4, FWAAS_DEFAULT_CHAIN, nsid)
self._remove_chain_by_name(IPV6, FWAAS_DEFAULT_CHAIN, nsid)
def _remove_chains(self, fwid, ipt_mgr):
"""Remove fwaas policy chain."""
for ver in [IPV4, IPV6]:
for direction in [INGRESS_DIRECTION, EGRESS_DIRECTION]:
chain_name = self._get_chain_name(fwid, ver, direction)
self._remove_chain_by_name(ver, chain_name, ipt_mgr)
def _add_default_policy_chain_v4v6(self, ipt_mgr):
ipt_mgr.ipv4['filter'].add_chain(FWAAS_DEFAULT_CHAIN)
ipt_mgr.ipv4['filter'].add_rule(FWAAS_DEFAULT_CHAIN, '-j DROP')
ipt_mgr.ipv6['filter'].add_chain(FWAAS_DEFAULT_CHAIN)
ipt_mgr.ipv6['filter'].add_rule(FWAAS_DEFAULT_CHAIN, '-j DROP')
def _remove_chain_by_name(self, ver, chain_name, ipt_mgr):
if ver == IPV4:
ipt_mgr.ipv4['filter'].remove_chain(chain_name)
else:
ipt_mgr.ipv6['filter'].remove_chain(chain_name)
def _add_rules_to_chain(self, ipt_mgr, ver, chain_name, rules):
if ver == IPV4:
table = ipt_mgr.ipv4['filter']
else:
table = ipt_mgr.ipv6['filter']
for rule in rules:
table.add_rule(chain_name, rule)
def _enable_policy_chain(self, fwid, ipt_if_prefix):
bname = iptables_manager.binary_name
ipt_mgr = ipt_if_prefix['ipt']
if_prefix = ipt_if_prefix['if_prefix']
for (ver, tbl) in [(IPV4, ipt_mgr.ipv4['filter']),
(IPV6, ipt_mgr.ipv6['filter'])]:
for direction in [INGRESS_DIRECTION, EGRESS_DIRECTION]:
chain_name = self._get_chain_name(fwid, ver, direction)
chain_name = iptables_manager.get_chain_name(chain_name)
if chain_name in tbl.chains:
jump_rule = ['%s %s+ -j %s-%s' % (IPTABLES_DIR[direction],
if_prefix, bname, chain_name)]
self._add_rules_to_chain(ipt_mgr,
ver, 'FORWARD', jump_rule)
#jump to DROP_ALL policy
chain_name = iptables_manager.get_chain_name(FWAAS_DEFAULT_CHAIN)
jump_rule = ['-o %s+ -j %s-%s' % (if_prefix, bname, chain_name)]
self._add_rules_to_chain(ipt_mgr, IPV4, 'FORWARD', jump_rule)
self._add_rules_to_chain(ipt_mgr, IPV6, 'FORWARD', jump_rule)
#jump to DROP_ALL policy
chain_name = iptables_manager.get_chain_name(FWAAS_DEFAULT_CHAIN)
jump_rule = ['-i %s+ -j %s-%s' % (if_prefix, bname, chain_name)]
self._add_rules_to_chain(ipt_mgr, IPV4, 'FORWARD', jump_rule)
self._add_rules_to_chain(ipt_mgr, IPV6, 'FORWARD', jump_rule)
def _convert_fwaas_to_iptables_rule(self, rule):
action = FWAAS_TO_IPTABLE_ACTION_MAP[rule.get('action')]
args = [self._protocol_arg(rule.get('protocol')),
self._port_arg('dport',
rule.get('protocol'),
rule.get('destination_port')),
self._port_arg('sport',
rule.get('protocol'),
rule.get('source_port')),
self._ip_prefix_arg('s', rule.get('source_ip_address')),
self._ip_prefix_arg('d', rule.get('destination_ip_address')),
self._action_arg(action)]
iptables_rule = ' '.join(args)
return iptables_rule
def _drop_invalid_packets_rule(self):
return '-m state --state INVALID -j DROP'
def _allow_established_rule(self):
return '-m state --state ESTABLISHED,RELATED -j ACCEPT'
def _action_arg(self, action):
if action:
return '-j %s' % action
return ''
def _protocol_arg(self, protocol):
if protocol:
return '-p %s' % protocol
return ''
def _port_arg(self, direction, protocol, port):
if not (protocol in ['udp', 'tcp'] and port):
return ''
return '--%s %s' % (direction, port)
def _ip_prefix_arg(self, direction, ip_prefix):
if ip_prefix:
return '-%s %s' % (direction, ip_prefix)
return ''
neutron-fwaas-8.0.0/neutron_fwaas/services/firewall/drivers/fwaas_base.py 0000664 0005670 0005671 00000007020 12701407720 030076 0 ustar jenkins jenkins 0000000 0000000 # Copyright 2013 Dell Inc.
# All Rights Reserved.
#
# 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.
import abc
import six
@six.add_metaclass(abc.ABCMeta)
class FwaasDriverBase(object):
"""Firewall as a Service Driver base class.
Using FwaasDriver Class, an instance of L3 perimeter Firewall
can be created. The firewall co-exists with the L3 agent.
One instance is created for each tenant. One firewall policy
is associated with each tenant (in the Havana release).
The Firewall can be visualized as having two zones (in Havana
release), trusted and untrusted.
All the 'internal' interfaces of Neutron Router is treated as trusted. The
interface connected to 'external network' is treated as untrusted.
The policy is applied on traffic ingressing/egressing interfaces on
the trusted zone. This implies that policy will be applied for traffic
passing from
- trusted to untrusted zones
- untrusted to trusted zones
- trusted to trusted zones
Policy WILL NOT be applied for traffic from untrusted to untrusted zones.
This is not a problem in Havana release as there is only one interface
connected to external network.
Since the policy is applied on the internal interfaces, the traffic
will be not be NATed to floating IP. For incoming traffic, the
traffic will get NATed to internal IP address before it hits
the firewall rules. So, while writing the rules, care should be
taken if using rules based on floating IP.
The firewall rule addition/deletion/insertion/update are done by the
management console. When the policy is sent to the driver, the complete
policy is sent and the whole policy has to be applied atomically. The
firewall rules will not get updated individually. This is to avoid problems
related to out-of-order notifications or inconsistent behaviour by partial
application of rules. Argument agent_mode indicates the l3 agent in DVR or
DVR_SNAT or LEGACY mode.
"""
@abc.abstractmethod
def create_firewall(self, agent_mode, apply_list, firewall):
"""Create the Firewall with default (drop all) policy.
The default policy will be applied on all the interfaces of
trusted zone.
"""
pass
@abc.abstractmethod
def delete_firewall(self, agent_mode, apply_list, firewall):
"""Delete firewall.
Removes all policies created by this instance and frees up
all the resources.
"""
pass
@abc.abstractmethod
def update_firewall(self, agent_mode, apply_list, firewall):
"""Apply the policy on all trusted interfaces.
Remove previous policy and apply the new policy on all trusted
interfaces.
"""
pass
@abc.abstractmethod
def apply_default_policy(self, agent_mode, apply_list, firewall):
"""Apply the default policy on all trusted interfaces.
Remove current policy and apply the default policy on all trusted
interfaces.
"""
pass
neutron-fwaas-8.0.0/neutron_fwaas/services/firewall/drivers/mcafee/ 0000775 0005670 0005671 00000000000 12701410073 026645 5 ustar jenkins jenkins 0000000 0000000 neutron-fwaas-8.0.0/neutron_fwaas/services/firewall/drivers/mcafee/ngfw_fwaas.py 0000664 0005670 0005671 00000026674 12701407720 031365 0 ustar jenkins jenkins 0000000 0000000 # Copyright 2015 Intel Corporation.
# Copyright 2015 Isaku Yamahata
#
# Copyright 2015 Yalei Wang
#
# All Rights Reserved.
#
# 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.
#
import netaddr
from neutron_lib import constants
from oslo_config import cfg
from oslo_log import helpers as log_helpers
from oslo_log import log as logging
from oslo_serialization import jsonutils
from neutron_fwaas._i18n import _
from neutron_fwaas.services.firewall.drivers import fwaas_base
from neutron_fwaas.services.firewall.drivers.mcafee import smc_api
NGFWOpts = [
cfg.StrOpt(
'smc_url',
default='',
help=_("URL to contact SMC server")
),
cfg.StrOpt(
'smc_api_auth_key',
default='',
help=_("Authentication key to SMC API")
),
cfg.StrOpt(
'smc_api_version',
default='',
help=_("verion of SMC API")
),
]
cfg.CONF.register_opts(NGFWOpts, 'ngfw')
LOG = logging.getLogger(__name__)
class NgfwFwaasDriver(fwaas_base.FwaasDriverBase):
"""Firewall driver for NGFW Fwaas of Mcafee """
def __init__(self):
LOG.debug("Initializing FWaas Mcafee NGFW driver")
super(NgfwFwaasDriver, self).__init__()
self._host_list = []
self._network_list = []
self._smc_url = cfg.CONF.ngfw.smc_url
self.fw_ips_template_ref = None
self.fw_template_ref = None
self.connection = smc_api.SMCAPIConnection(
self._smc_url,
cfg.CONF.ngfw.smc_api_version,
cfg.CONF.ngfw.smc_api_auth_key)
@log_helpers.log_method_call
def create_firewall(self, agent_mode, apply_list, firewall):
# call update_firewall, because one tenant only support
# one firewall
return self.update_firewall(agent_mode, apply_list, firewall)
@log_helpers.log_method_call
def delete_firewall(self, agent_mode, apply_list, firewall):
# tell SMC server to remove the ngfw policy
return self._delete_policy(apply_list, firewall)
@log_helpers.log_method_call
def update_firewall(self, agent_mode, apply_list, firewall):
for router_info in apply_list:
rt = router_info.router
# only update the policy when the router is active
if (rt['tenant_id'] == firewall['tenant_id'] and
rt['status'] == 'ACTIVE'):
self._update_policy(rt, firewall)
def _delete_policy(self, apply_list, firewall):
for router_info in apply_list:
rt = router_info.router
self._clear_policy(rt, firewall)
@log_helpers.log_method_call
def apply_default_policy(self, apply_list, firewall):
return self._delete_policy(apply_list, firewall)
def _update_policy(self, router, firewall):
# clear all the policy first
self._clear_policy(router, firewall)
if firewall['admin_state_up']:
self._setup_policy(router, firewall)
def _is_ips_policy(self, policy_name):
return policy_name[len(policy_name) - 4:].lower() == '-ips'
def _get_policy_ref(self, policy_name):
# get the template ref at the first time
if not self.fw_ips_template_ref or not self.fw_template_ref:
r = self.connection.get('elements/fw_template_policy')
fw_template_list = r[0]['result']
for tplt in fw_template_list:
if tplt['name'] == "Firewall Inspection Template":
self.fw_ips_template_ref = tplt['href'].replace(
self._smc_url +
"/%s/" % cfg.CONF.ngfw.smc_api_version,
'')
elif tplt['name'] == "Firewall Template":
self.fw_template_ref = tplt['href'].replace(
self._smc_url +
"/%s/" % cfg.CONF.ngfw.smc_api_version,
'')
# use different template base on the policy name
if self._is_ips_policy(policy_name):
template = self.fw_ips_template_ref
else:
template = self.fw_template_ref
# create the policy in SMC server
fw_policy = {
"name": policy_name,
"template": template
}
ref = self._get_ref_from_service_data('fw_policy', fw_policy)
return ref
def _parse_port(self, source_port):
min_port = ''
max_port = ''
if source_port is None:
min_port = 0
max_port = 65535
elif ':' in source_port:
ports = source_port.split(':')
min_port = int(ports[0])
max_port = int(ports[1])
else:
min_port = int(source_port)
max_port = ''
return min_port, max_port
def _get_ref_from_addr(self, addr):
if addr == 'None':
return addr
ip = netaddr.IPNetwork(addr)
if str(ip.netmask) != "255.255.255.255":
# create network objects
ref = self._create_network(addr)
else:
# create host objects
ref = self._create_host(str(ip.ip))
return ref
def _get_ref_from_service_data(self, service_path, service_data):
json_data = jsonutils.dumps(service_data)
r = self.connection.post_element(service_path, json_data)
srv_ref = r.headers['location']
return srv_ref
def _convert_ipv4_to_ngfw_rule(self, rule):
# convert the ipv4 rule into ngfw rules
# create src/dst of hosts or networks
src_ref = self._get_ref_from_addr(str(rule['source_ip_address']))
dst_ref = self._get_ref_from_addr(str(rule['destination_ip_address']))
# create service
srv_ref = ''
service_dict = {}
service = "%s_service" % rule['protocol']
if rule['protocol'] in (constants.PROTO_NAME_TCP,
constants.PROTO_NAME_UDP):
source_port = rule['source_port']
dest_port = rule['destination_port']
min_src_port, max_src_port = self._parse_port(source_port)
min_dst_port, max_dst_port = self._parse_port(dest_port)
service_data = {
"name": "service-%s" % rule['name'],
"min_src_port": min_src_port,
"max_src_port": (min_src_port if max_src_port == ''
else max_src_port),
"min_dst_port": min_dst_port,
"max_dst_port": (min_dst_port if max_dst_port == ''
else max_dst_port)
}
srv_ref = self._get_ref_from_service_data(service,
service_data)
service_dict = {"service": [srv_ref]}
elif rule['protocol'] == constants.PROTO_NAME_ICMP:
# only ping is supported
service_data = {
"name": "service%s" % "22",
"icmp_type": 0,
"icmp_code": 0
}
srv_ref = self._get_ref_from_service_data(service,
service_data)
service_dict = {"service": [srv_ref]}
elif rule['protocol'] is None:
# protocol "ANY" is translated to accept all, no service create
# here
# TODO(yalie): add rules for different protocol, not ignore the
# other value like ports.
service_dict = {"any": True}
else:
raise NotImplementedError(
_("not support %s protocol now") % rule['protocol'])
# create fw rule
action = "discard" if rule["action"] == "deny" else "allow"
payload = {
"name": rule['name'],
"action": {
"action": action,
"connection_tracking_options": {}
},
"destinations": {"dst": [dst_ref]},
"services": service_dict,
"sources": {"src": [src_ref]}
}
json_data = jsonutils.dumps(payload)
return json_data
def _get_policy_name(self, router, fw):
# SMC server would bind the different NGFW policy with different
# routers(sg-engine) in a tenant
return "%s_%s_%s" % (
fw['id'][0:7], fw['firewall_policy_id'][0:7], router['id'][0:7])
def _setup_policy(self, router, fw):
# one tenant should use only one policy
with self.connection.login_server():
# create policy ref
policy_name = self._get_policy_name(router, fw)
policy_ref = self._get_policy_ref(policy_name)
# post service
for rule in fw['firewall_rule_list']:
if not rule['enabled']:
continue
if rule['ip_version'] == 4:
json_data = self._convert_ipv4_to_ngfw_rule(rule)
self.connection.post(policy_ref +
"/fw_ipv4_access_rule",
json_data, raw=True)
else:
msg = (_('Unsupported IP version rule. %(version)') %
{'version': rule['ip_version']})
raise ValueError(msg)
# upload the policy
self.connection.post(policy_ref + "/upload", '', raw=True)
def _clear_policy(self, router, fw):
# find the policy used by the tenant and firewall
policy_name = self._get_policy_name(router, fw)
path_policy_filter = 'elements/fw_policy?filter=%s' % policy_name
with self.connection.login_server():
r = self.connection.get(path=path_policy_filter)
fw_list = r[0]['result']
for f in fw_list:
if f['name'] == policy_name:
self.connection.delete(f['href'], raw=True)
# Warning, find unused elements and delete them.
r = self.connection.get(path='elements/search_unused')
element_list = r[0]['result']
for element in element_list:
self.connection.delete(element['href'], raw=True)
def _create_host(self, ip):
ref = None
host_json_def = {
"name": "host-%s" % str(ip),
"address": ip
}
with self.connection.login_server():
ref = self._get_ref_from_service_data('host', host_json_def)
return ref
def _create_network(self, cidr):
ref = None
net_json_def = {
"name": "network-%s" % str(cidr),
"ipv4_network": cidr
}
with self.connection.login_server():
# some network maybe pre-created by router-plugin
r = self.connection.get("elements/network")
networks = r[0]['result']
for net in networks:
if net['name'] == "network-%s" % cidr:
ref = net['href']
return ref
ref = self._get_ref_from_service_data('network', net_json_def)
return ref
neutron-fwaas-8.0.0/neutron_fwaas/services/firewall/drivers/mcafee/constants.py 0000664 0005670 0005671 00000021665 12701407720 031252 0 ustar jenkins jenkins 0000000 0000000 # Copyright 2015 Intel Corporation.
# Copyright 2015 Yalei Wang
#
# All Rights Reserved.
#
# 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.
JSON_PHY_INTERFACES = 'physicalInterfaces'
JSON_NAME = 'name'
JSON_NODES = 'nodes'
JSON_LOG_SERVER_REF = 'log_server_ref'
JSON_NODE_NET_VALUE = 'network_value'
JSON_NODE_NET_ADDR = 'address'
JSON_PHY_INTF = 'physical_interface'
L2_ELEMENT_TEMPLATE = ("""
{
'log_server_ref':
'http://localhost:8082/5.7/elements/log_server/1441',
'name': '@PLACE_HOLDER@ L2 FW',
'nodes':
[
{
'fwlayer2_node': {
'name': '@PLACE_HOLDER@ L2 FW node 1',
'nodeid': 1
}
}
],
'physicalInterfaces':
[
{
'physical_interface': {
'interface_id': '1',
'interfaces':
[
{
'inline_interface': {
'failure_mode': 'normal',
'logical_interface_ref':
'http://localhost:8082/5.7/elements/logical_interface/1',
'nicid': '1-2'
}
}
]
}
},
{
'physical_interface': {
'interface_id': '0',
'interfaces':
[
{
'node_interface': {
'address': '192.168.2.10',
'network_value': '192.168.2.0/24',
'nicid': '0',
'nodeid': 1,
'outgoing': true,
'primary_mgt': true
}
}
]
}
},
{
'physical_interface': {
'interface_id': '3',
'interfaces':
[
{
'capture_interface': {
'logical_interface_ref':
'http://localhost:8082/5.7/elements/logical_interface/1073741835',
'nicid': '3'
}
}
]
}
}
]
}
""")
L3_ELEMENT_TEMPLATE = ("""
{
"alias_value": [
],
"antivirus": {
"antivirus_enabled": false,
"virus_log_level": "none",
"virus_mirror": "database.clamav.net"
},
"auto_reboot_timeout": 10,
"connection_limit": 0,
"connection_timeout": [
{
"protocol": "icmp",
"timeout": 5
},
{
"protocol": "other",
"timeout": 180
},
{
"protocol": "tcp",
"timeout": 1800
},
{
"protocol": "udp",
"timeout": 50
}
],
"contact_timeout": 60000,
"default_nat": false,
"domain_server_address": [
],
"dos_protection": "always_off",
"excluded_interface": -1,
"is_cert_auto_renewal": true,
"is_config_encrypted": true,
"is_fips_compatible_operating_mode": false,
"is_loopback_tunnel_ip_address_enforced": false,
"is_virtual_defrag": true,
"log_moderation": [
{
"burst": 1000,
"log_event": "1",
"rate": 100
},
{
"log_event": "2"
}
],
"log_server_ref": "@PLACE_HOLDER@",
"log_spooling_policy": "discard",
"loopback_cluster_virtual_interface": [
],
"name": "@PLACE_HOLDER@",
"nodes": [
{
"firewall_node": {
"activate_test": true,
"disabled": false,
"loopback_node_dedicated_interface": [
],
"name": "@NODE_NAME_PLACE_HOLDER@",
"nodeid": 1
}
}
],
"passive_discard_mode": false,
"physicalInterfaces": [
],
"read_only": false,
"rollback_timeout": 60,
"scan_detection": {
"scan_detection_icmp_events": 252,
"scan_detection_icmp_timewindow": 60,
"scan_detection_tcp_events": 252,
"scan_detection_tcp_timewindow": 60,
"scan_detection_type": "default off",
"scan_detection_udp_events": 252,
"scan_detection_udp_timewindow": 60
},
"slow_request_blacklist_timeout": 300,
"slow_request_sensitivity": "off",
"strict_tcp_mode": false,
"syn_flood_sensitivity": "off",
"syn_mode": "off",
"system": false,
"tcp_reset_sensitivity": "OFF",
"tester_parameters": {
"alert_interval": 3600,
"auto_recovery": true,
"boot_delay": 30,
"boot_recovery": true,
"restart_delay": 5,
"status_delay": 5
},
"tracking_mode": "normal"
}
""")
PHYSICAL_INTERFACE_TEMPLATE = ("""
{
"physical_interface": {
"aggregate_mode": "none",
"arp_entry": [
],
"cvi_mode": "none",
"dhcp_server_on_interface": {
"dhcp_range_per_node": [
]
},
"interface_id": "@PLACE_HODLER@",
"interfaces": [
{
"single_node_interface": {
"address": "@PLACE_HOLDER_IP@",
"auth_request": false,
"auth_request_source": false,
"backup_heartbeat": false,
"backup_mgt": false,
"dynamic_ip": false,
"igmp_mode": "none",
"key": 200,
"modem": false,
"network_value": "@PLACE_HOLDER_IP_NETWORK@",
"nicid": "0",
"nodeid": 1,
"outgoing": false,
"pppoa": false,
"pppoe": false,
"primary_heartbeat": false,
"primary_mgt": false,
"relayed_by_dhcp": false,
"reverse_connection": false,
"vrrp": false,
"vrrp_id": -1,
"vrrp_priority": -1
}
}
],
"log_moderation": [
{
"burst": 1000,
"log_event": "1",
"rate": 100
},
{
"log_event": "2"
}
],
"managed_address_flag": false,
"mtu": -1,
"other_configuration_flag": false,
"qos_limit": -1,
"qos_mode": "no_qos",
"router_advertisement": false,
"syn_mode": "default",
"virtual_engine_vlan_ok": false,
"vlanInterfaces": [
]
}
}
""")
neutron-fwaas-8.0.0/neutron_fwaas/services/firewall/drivers/mcafee/smc_api.py 0000664 0005670 0005671 00000040662 12701407721 030650 0 ustar jenkins jenkins 0000000 0000000 # Copyright 2015 Intel Corporation.
# Copyright 2015 Isaku Yamahata
#
# Copyright 2015 Yalei Wang
#
# All Rights Reserved.
#
# 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.
#
# This script uses SMC-API to get/post elements from SMC server
#
import abc
import netaddr
import requests
import six
from contextlib import contextmanager
from neutron.common import exceptions as n_exc
from oslo_log import log as logging
from oslo_serialization import jsonutils
from neutron_fwaas._i18n import _, _LE, _LI, _LW
from neutron_fwaas.services.firewall.drivers.mcafee import constants as const
LOG = logging.getLogger(__name__)
class SMCAPIResult(object):
"""Class for returning result to API caller"""
def __init__(self, tp):
self.type = tp
self.result = "N/A"
self.code = "200"
self.headers = None
def is_json(self):
return self.type == "json"
def is_text(self):
return self.type == "text"
def __str__(self):
return self.result
class SMCAPIConnection(object):
"""Provide the REST API method to connect to the SMC server.
For login/logout operation, users should set server IP, API version and
auth key first. For get/put/delete operation, users should provide the
target element's path and special json format data section following "SMC
API User's Guide".
"""
def __init__(self, host, api_version, authentication_key):
self.cookies = {}
self.host = host
self.api_version = api_version
self.host_api_url = self.host + "/" + self.api_version
self.auth_key = authentication_key
self.session = None
@contextmanager
def login_server(self):
if self.session:
yield
else:
ret = self.login()
LOG.debug("SMC server LOGIN successfully.")
if ret:
try:
yield
except Exception:
LOG.exception(_LE("exception while connect to server!"))
raise n_exc.ServiceUnavailable(resource='SMC server',
msg=_("OPERATION failed"))
finally:
self.logout()
else:
raise n_exc.BadRequest(resource='SMC server',
msg=_("LOGIN failed!"))
def login(self):
self.session = requests.session()
post_addr = ("%s/login?authenticationkey=%s&beta=true" %
(self.host_api_url, self.auth_key))
res = self.session.post(post_addr)
if res.status_code == 200:
return True
LOG.error(_LE("connect to %(host)s failed"
" (%(msg)s/ code %(code)s)"),
{'host': post_addr,
'msg': res.reason,
'code': res.status_code})
return False
def logout(self):
result = self.session.put("%s/logout" % (self.host_api_url))
self.session = None
LOG.debug("LOGOUT from SMC server result %s", result)
def session_op(self, attr, path, raw=False, data=None, headers=None):
op = getattr(self.session, attr)
if raw:
result = op(path, headers=headers, data=data)
else:
result = op("%s/%s" %
(self.host_api_url, path), headers=headers, data=data)
if result.status_code == "404":
LOG.error(_LE("SMC Error 404 %s"), result.reason)
return result
def get(self, path, etag=None, raw=False):
json_result = None
etag_out = None
headers = {'accept': 'application/json',
'content-type': 'application/json'}
if etag:
headers['ETag'] = etag
try:
result = self.session_op("get", path, raw, headers=headers)
if 'etag' in result.headers:
etag_out = result.headers['etag']
json_result = result.json()
if result.status_code == "404":
LOG.error(_LE("%(msg)s %(detail)s"),
{'msg': json_result["message"],
'detail': json_result["details"]})
except Exception:
LOG.error(_LE("exception when GET operation"))
raise
r = [json_result]
if etag_out:
r.append(etag_out)
return [json_result]
def check_ret(self, string, path, ret, updated_result):
if ret.status_code != 200:
LOG.info(_LI("%(str)s ELEMENT result code: %(stat)d "
"%(path)s %(reason)s text=%(text)s"),
{'str': string, 'path': path,
'stat': ret.status_code,
'reason': ret.reason,
'text': ret.text})
updated_result.type = "text"
updated_result.result = ret.text
else:
if ret.headers.get('content-type') == "application/json":
updated_result.type = "json"
updated_result.result = ret.json
else:
updated_result.type = "text"
updated_result.result = ret.content
updated_result.code = ret.status_code
def delete(self, path, raw=False):
del_result = SMCAPIResult("text")
try:
result = self.session_op("delete", path, raw)
self.check_ret("DELETE", path, result, del_result)
except Exception:
LOG.error(_LE("exception when DELETE operation"))
raise
return del_result
def post(self, path, json_element, raw=False):
headers = {'accept': '*/*',
'content-type': 'application/json'}
post_result = SMCAPIResult("text")
try:
result = self.session_op(
"post", path, raw, headers=headers, data=json_element)
self.check_ret("POST", path, result, post_result)
post_result.headers = result.headers
except Exception:
LOG.error(_LE("exception when POST operation"))
raise
return post_result
def post_element(self, element_type, json_element):
return self.post("elements/%s" % (element_type), json_element)
@six.add_metaclass(abc.ABCMeta)
class SMCAPIElement(object):
"""
Base class of elements, used by L2/L3 single firewall class
"""
element_type = "N/A"
@staticmethod
def usage(extra_info=None):
if extra_info:
LOG.error(_LE("Error -> %s"), extra_info)
raise ValueError(_('Wrong initial data!'))
def __init__(self, name, smc_api_connection, control_ip=None):
if not name:
self.usage("name of element missing.")
self.name = name
self.element_id = 0
self.json_element = None
self.element_template = None
self.smc_api_connection = smc_api_connection
self.keyboard = None
self.timezone = None
if control_ip:
self.control_ip = netaddr.IPNetwork(control_ip)
if self.control_ip.prefixlen == 32:
self.usage(
"Control_ip %s needs to netmask bits e.g x.x.x.x/yy"
% (self.control_ip))
else:
self.control_ip = None
def to_json(self):
return jsonutils.dumps(self.json_element)
@abc.abstractmethod
def create(self):
raise NotImplementedError(
"not support SMCAPIElement create")
@abc.abstractmethod
def update(self):
raise NotImplementedError(
"not support SMCAPIElement update")
@abc.abstractmethod
def delete(self):
raise NotImplementedError(
"not support SMCAPIElement delete")
def get_element(self, path):
LOG.debug("Getting path: %s", path)
return self.smc_api_connection.get("elements/%s" % (path))
def get_elements(self, element_type=None):
if not element_type:
element_type = self.element_type
return self.smc_api_connection.get("elements/%s" % (element_type))
def fetch_element_id(self):
json_result = self.get_elements()
if not json_result[0]['result']:
LOG.warning(_LW("No #{element_type} defined in SMC"))
else:
for element in json_result[0]['result']:
href = element['href']
self.element_id = int(href.split('/')[-1])
if element['name'] == self.name:
LOG.debug("%(type)s element with name %(name)s FOUND "
"%(href)s",
{'type': self.element_type,
'name': self.name,
'href': href})
break
LOG.debug("Got ID %s", self.element_id)
return self.element_id
def get_initial_contact_data(self):
"""Get the element's configuration data used to contact to SMC server.
Contact data is a configuration string including the SMC server's IP,
interfaces defined and special one-time password.
eg. first create the L3 element on behalf of sg-engine in SMC server
and generate the contact data, then boot the sg-engine with it and
engine will init properly and connect to SMC server finally.
"""
data = None
result = self.get_element("%s/%s/node" %
(self.element_type, self.element_id))
LOG.debug("resule = %s", result)
node_ref = result[0]['result'][0]['href'].replace(
self.smc_api_connection.host_api_url + "/elements/", "")
LOG.debug("Node ref is %s", node_ref)
extra_options = []
if self.keyboard:
extra_options.append("keyboard=%s" % (self.keyboard))
if self.timezone:
extra_options.append("time_zone=%s" % (self.timezone))
if extra_options:
extra_options = "&" + extra_options
else:
extra_options = ""
result = self.smc_api_connection.post_element(
"%s/initial_contact?enable_ssh=true%s" %
(node_ref, extra_options), "")
if result.is_text():
d1 = str(result).split("\n")
idx = 0
for l in d1:
if l.find("ssh/enabled") != -1:
l = l.replace("false", "true")
d1[idx] = l
idx += 1
result.result = "\n".join(d1)
data = result
result = self.smc_api_connection.post_element(
"%s/bind_license" % (node_ref), "")
if result.code != 200:
LOG.error(_LE("Could not bind license. "
"Maybe SMC license pool is empty. "
"SMC API details: %s"), result)
return data
class SMCAPIElementL2FWSingle(SMCAPIElement):
"""L2 single firewall element."""
element_type = "single_layer2"
def __init__(self, name, smc_api_connection, control_ip):
SMCAPIElement.__init__(self, name, smc_api_connection, control_ip)
self.element_id = 0
self.json_element = None
def create(self):
json_result = self.get_elements("log_server")
log_server_ref = json_result[0]['result'][0]['href']
LOG.debug("Using log server '%(name)s', ref %(ref)s",
{'name': json_result[0]['result'][0]['name'],
'ref': log_server_ref})
json_result = self.get_elements("logical_interface")
logical_interfaces = dict((logical_iface['name'],
logical_iface['href']) for logical_iface in
json_result[0]['result'] if logical_iface['name']
in ('default_eth', 'capture'))
for name, ref in six.iteritems(logical_interfaces):
LOG.debug("Using logical interface %(name)s ref %(href)s",
{'name': name, 'href': ref})
json_data = jsonutils.loads(const.L2_ELEMENT_TEMPLATE)
json_data[const.JSON_LOG_SERVER_REF] = log_server_ref
json_data[const.JSON_NAME] = self.name
json_data[const.JSON_NODES][0]['fwlayer2_node']['name'] = (self.name +
" node 1")
physical_ifaces = json_data[const.JSON_PHY_INTERFACES]
for phys_iface in physical_ifaces:
for iface in phys_iface[const.JSON_PHY_INTF]['interfaces']:
if 'inline_interface' in iface:
inline_iface = iface['inline_interface']
inline_iface['logical_interface_ref'] = (
logical_interfaces['default_eth']['href'])
elif 'capture_interface' in iface:
capture_iface = iface['capture_interface']
capture_iface['logical_interface_ref'] = (
logical_interfaces['capture']['href'])
elif 'node_interface' in iface:
node_iface = iface['node_interface']
if not node_iface['primary_mgt']:
continue
node_iface[const.JSON_NODE_NET_ADDR] = (
str(self.control_ip.ip))
node_iface[const.JSON_NODE_NET_VALUE] = (
str(self.control_ip.cidr))
self.json_element = json_data
self.smc_api_connection.post_element(self.element_type, self.to_json())
self.fetch_element_id()
def update(self):
"""Update element """
pass
def delete(self):
"""Delete element """
pass
class SMCAPIElementL3FWSingle(SMCAPIElement):
"""L3 single firewall element."""
element_type = "single_fw"
def __init__(self, name, smc_api_connection, control_ip):
super(SMCAPIElementL3FWSingle, self).__init__(self, name,
smc_api_connection, control_ip)
self.element_id = 0
self.json_element = None
self.physical_interfaces = []
def modify_interface_property(self, physical_interface, name, value):
iface = physical_interface[const.JSON_PHY_INTF]
iface = iface['interfaces'][0]['single_node_interface']
iface[name] = value
def add_physical_interface(self, ip_and_network, interface_id):
ip = netaddr.IPNetwork(ip_and_network)
json_data = jsonutils.loads(const.PHYSICAL_INTERFACE_TEMPLATE)
phys_iface = json_data[const.JSON_PHY_INTF]
phys_iface['interface_id'] = interface_id
iface = json_data[const.JSON_PHY_INTF]['interfaces'][0]
iface = iface['single_node_interface']
iface[const.JSON_NODE_NET_ADDR] = str(ip.ip)
iface[const.JSON_NODE_NET_VALUE] = str(ip.cidr)
self.physical_interfaces.append(json_data)
return json_data
def create(self):
json_result = self.get_elements("log_server")
log_server_ref = json_result[0]['result'][0]['href']
LOG.debug(
"Using log server '%(name)s' ref %(ref)s",
{'name': json_result[0]['result'][0]['name'],
'ref': log_server_ref})
json_data = jsonutils.loads(const.L3_ELEMENT_TEMPLATE)
json_data[const.JSON_LOG_SERVER_REF] = log_server_ref
json_data[const.JSON_NAME] = self.name
json_data[const.JSON_NODES][0]['firewall_node']['name'] = (self.name +
" node 1")
iface = self.add_physical_interface(self.control_ip, 0)
self.modify_interface_property(iface, "primary_mgt", True)
for phys_iface in self.physical_interfaces:
json_data[const.JSON_PHY_INTERFACES].append(phys_iface)
LOG.debug("%s",
jsonutils.dumps(json_data, sort_keys=False,
indent=2, separators=(',', ': ')))
self.json_element = json_data
self.smc_api_connection.post_element(self.element_type, self.to_json())
self.fetch_element_id()
neutron-fwaas-8.0.0/neutron_fwaas/services/firewall/drivers/mcafee/__init__.py 0000664 0005670 0005671 00000000000 12701407720 030751 0 ustar jenkins jenkins 0000000 0000000 neutron-fwaas-8.0.0/neutron_fwaas/services/firewall/drivers/mcafee/README.rst 0000664 0005670 0005671 00000000515 12701407720 030342 0 ustar jenkins jenkins 0000000 0000000 Mcafee NGFW Firewall as a Service Driver
* For more information, refer to:
https://wiki.openstack.org/wiki/Mcafee_NGFW_Firewall_driver
* For information on Intel NGFW CI, refer to:
https://wiki.openstack.org/wiki/ThirdPartySystems/Intel_NGFW_CI
* Intel NGFW CI contact:
- yalei.wang@intel.com
- rui.zang@intel.com
neutron-fwaas-8.0.0/neutron_fwaas/services/firewall/drivers/varmour/ 0000775 0005670 0005671 00000000000 12701410073 027120 5 ustar jenkins jenkins 0000000 0000000 neutron-fwaas-8.0.0/neutron_fwaas/services/firewall/drivers/varmour/__init__.py 0000775 0005670 0005671 00000000000 12701407720 031227 0 ustar jenkins jenkins 0000000 0000000 neutron-fwaas-8.0.0/neutron_fwaas/services/firewall/drivers/varmour/varmour_fwaas.py 0000775 0005670 0005671 00000016437 12701407720 032371 0 ustar jenkins jenkins 0000000 0000000 # Copyright 2013 vArmour Networks Inc.
# All Rights Reserved.
#
# 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.
from oslo_log import log as logging
from neutron_fwaas._i18n import _LW
from neutron_fwaas.services.firewall.agents.varmour import varmour_api
from neutron_fwaas.services.firewall.agents.varmour \
import varmour_utils as va_utils
from neutron_fwaas.services.firewall.drivers import fwaas_base
LOG = logging.getLogger(__name__)
class vArmourFwaasDriver(fwaas_base.FwaasDriverBase):
def __init__(self):
LOG.debug("Initializing fwaas vArmour driver")
self.fake_agent_mode = None
self.rest = varmour_api.vArmourRestAPI()
def create_firewall(self, agent_mode, apply_list, firewall):
LOG.debug('create_firewall (%s)', firewall['id'])
return self.update_firewall(self.fake_agent_mode, apply_list, firewall)
def update_firewall(self, agent_mode, apply_list, firewall):
LOG.debug("update_firewall (%s)", firewall['id'])
if firewall['admin_state_up']:
return self._update_firewall(apply_list, firewall)
else:
return self.apply_default_policy(apply_list, firewall)
def delete_firewall(self, agent_mode, apply_list, firewall):
LOG.debug("delete_firewall (%s)", firewall['id'])
return self.apply_default_policy(self.fake_agent_mode, apply_list,
firewall)
def apply_default_policy(self, agent_mode, apply_list, firewall):
LOG.debug("apply_default_policy (%s)", firewall['id'])
self.rest.auth()
for ri in apply_list:
self._clear_policy(ri, firewall)
return True
def _update_firewall(self, apply_list, firewall):
LOG.debug("Updating firewall (%s)", firewall['id'])
self.rest.auth()
for ri in apply_list:
self._clear_policy(ri, firewall)
self._setup_policy(ri, firewall)
return True
def _setup_policy(self, ri, fw):
# create zones no matter if they exist. Interfaces are added by router
body = {
'type': 'L3',
'interface': []
}
body['name'] = va_utils.get_trusted_zone_name(ri)
self.rest.rest_api('POST', va_utils.REST_URL_CONF_ZONE, body)
body['name'] = va_utils.get_untrusted_zone_name(ri)
self.rest.rest_api('POST', va_utils.REST_URL_CONF_ZONE, body)
self.rest.commit()
servs = dict()
addrs = dict()
for rule in fw['firewall_rule_list']:
if not rule['enabled']:
continue
if rule['ip_version'] == 4:
service = self._make_service(ri, fw, rule, servs)
s_addr = self._make_address(ri, fw, rule, addrs, True)
d_addr = self._make_address(ri, fw, rule, addrs, False)
policy = va_utils.get_firewall_policy_name(ri, fw, rule)
z0 = va_utils.get_trusted_zone_name(ri)
z1 = va_utils.get_untrusted_zone_name(ri)
body = self._make_policy(policy + '_0', rule,
z0, z0, s_addr, d_addr, service)
self.rest.rest_api('POST', va_utils.REST_URL_CONF_POLICY, body)
body = self._make_policy(policy + '_1', rule,
z0, z1, s_addr, d_addr, service)
self.rest.rest_api('POST', va_utils.REST_URL_CONF_POLICY, body)
body = self._make_policy(policy + '_2', rule,
z1, z0, s_addr, d_addr, service)
self.rest.rest_api('POST', va_utils.REST_URL_CONF_POLICY, body)
self.rest.commit()
else:
LOG.warning(_LW("Unsupported IP version rule."))
def _clear_policy(self, ri, fw):
prefix = va_utils.get_firewall_object_prefix(ri, fw)
self.rest.del_cfg_objs(va_utils.REST_URL_CONF_POLICY, prefix)
self.rest.del_cfg_objs(va_utils.REST_URL_CONF_ADDR, prefix)
self.rest.del_cfg_objs(va_utils.REST_URL_CONF_SERVICE, prefix)
def _make_service(self, ri, fw, rule, servs):
prefix = va_utils.get_firewall_object_prefix(ri, fw)
if rule.get('protocol'):
key = rule.get('protocol')
if rule.get('source_port'):
key += '-' + rule.get('source_port')
if rule.get('destination_port'):
key += '-' + rule.get('destination_port')
else:
return
if key in servs:
name = '%s_%d' % (prefix, servs[key])
else:
# create new service object with index
idx = len(servs)
servs[key] = idx
name = '%s_%d' % (prefix, idx)
body = {'name': name}
self.rest.rest_api('POST',
va_utils.REST_URL_CONF_SERVICE,
body)
body = self._make_service_rule(rule)
self.rest.rest_api('POST',
va_utils.REST_URL_CONF +
va_utils.REST_SERVICE_NAME % name,
body)
self.rest.commit()
return name
def _make_service_rule(self, rule):
body = {
'name': '1',
'protocol': rule.get('protocol')
}
if 'source_port' in rule:
body['source-start'] = rule['source_port']
body['source-end'] = rule['source_port']
if 'destination_port' in rule:
body['dest-start'] = rule['destination_port']
body['dest-end'] = rule['destination_port']
return body
def _make_address(self, ri, fw, rule, addrs, is_src):
prefix = va_utils.get_firewall_object_prefix(ri, fw)
if is_src:
key = rule.get('source_ip_address')
else:
key = rule.get('destination_ip_address')
if not key:
return
if key in addrs:
name = '%s_%d' % (prefix, addrs[key])
else:
# create new address object with idx
idx = len(addrs)
addrs[key] = idx
name = '%s_%d' % (prefix, idx)
body = {
'name': name,
'type': 'ipv4',
'ipv4': key
}
self.rest.rest_api('POST', va_utils.REST_URL_CONF_ADDR, body)
self.rest.commit()
return name
def _make_policy(self, name, rule, zone0, zone1, s_addr, d_addr, service):
body = {
'name': name,
'action': 'permit' if rule.get('action') == 'allow' else 'deny',
'from': zone0,
'to': zone1,
'match-source-address': [s_addr or 'Any'],
'match-dest-address': [d_addr or 'Any'],
'match-service': [service or 'Any']
}
return body
neutron-fwaas-8.0.0/neutron_fwaas/services/firewall/drivers/cisco/ 0000775 0005670 0005671 00000000000 12701410073 026525 5 ustar jenkins jenkins 0000000 0000000 neutron-fwaas-8.0.0/neutron_fwaas/services/firewall/drivers/cisco/csr_acl_driver.py 0000664 0005670 0005671 00000032523 12701407720 032072 0 ustar jenkins jenkins 0000000 0000000 # Copyright 2014 Cisco Systems, Inc.
# All Rights Reserved.
#
# 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.
import requests
from networking_cisco.plugins.cisco.cfg_agent.device_drivers import (
cisco_csr_rest_client)
from oslo_log import log as logging
from neutron_fwaas._i18n import _LE
from neutron_fwaas.services.firewall.drivers import fwaas_base
LOG = logging.getLogger(__name__)
#----- ACL REST URL definitions -------------------------------------------
ACL_API = 'acl'
ACL_API_ACLID = 'acl/%s' # ACLID
ACL_API_ACLID_IF = 'acl/%s/interfaces' # ACLID
ACL_API_ACLID_IFID_DIR = 'acl/%s/interfaces/%s_%s' # ACLID, IF_DIRECTION
class CsrAclDriver(fwaas_base.FwaasDriverBase):
"""Cisco CSR ACL driver for FWaaS.
This driver will send ACL configuration via RESTAPI to CSR1kv.
This driver will return error to the caller function in case of
error such as validation failures, sending configuration failures.
The caller function will handle the error return properly.
"""
def __init__(self):
LOG.debug("Initializing fwaas CSR ACL driver")
def _get_csr_host(self, firewall_vendor_ext):
settings = {
'rest_mgmt_ip': firewall_vendor_ext['host_mngt_ip'],
'username': firewall_vendor_ext['host_usr_nm'],
'password': firewall_vendor_ext['host_usr_pw'],
'timeout': 30,
}
return cisco_csr_rest_client.CsrRestClient(settings)
def _validate_firewall_rule_data(self, firewall):
if 'firewall_rule_list' not in firewall:
LOG.error(_LE("no rule list"))
return False
for rule in firewall['firewall_rule_list']:
if 'name' not in rule:
LOG.error(_LE("CsrAcl: no rule name"))
return False
ip_version = rule.get('ip_version')
if ip_version != 4:
LOG.error(_LE("invalid ip version %(ip_version)s in "
"rule %(rule)s"),
{'ip_version': ip_version, 'rule': rule['name']})
return False
if 'protocol' not in rule:
LOG.error(_LE("no protocol in rule [%s]"), rule['name'])
return False
if rule.get('action', '').lower() not in ('allow', 'deny'):
LOG.error(_LE("invalid action in rule [%s]"), rule['name'])
return False
return True
def _validate_firewall_data(self, firewall):
data = ('admin_state_up', 'vendor_ext')
is_valid = all(x in firewall for x in data)
if not is_valid:
LOG.error(_LE("missing data in firewall"))
return is_valid
data = ('host_mngt_ip', 'host_usr_nm', 'host_usr_pw', 'if_list')
is_valid = all(x in firewall['vendor_ext'] for x in data)
if not is_valid:
LOG.error(_LE("missing data in firewall vendor_ext"))
return is_valid
for firewall_interface in firewall['vendor_ext']['if_list']:
if firewall_interface.get('direction', '') not in (
'inside', 'outside', 'both'):
LOG.error(_LE("invalid direction"))
return False
if 'port' not in firewall_interface:
LOG.error(_LE("no port"))
return False
port = firewall_interface['port']
if 'id' not in port:
LOG.error(_LE("no port id"))
return False
if 'hosting_info' not in port:
LOG.error(_LE("no hosting_info"))
return False
if 'segmentation_id' not in port['hosting_info']:
LOG.error(_LE("no segmentation_id"))
return False
if 'hosting_port_name' not in port['hosting_info']:
LOG.error(_LE("hosting_port_name"))
return False
interface_type = port['hosting_info'][
'hosting_port_name'].split(':')[0] + ':'
if interface_type not in ('t1_p:', 't2_p:'):
LOG.error(_LE("invalide interface type %s"), interface_type)
return False
return True
def _get_acl_l4_port(self, rule_port_name, rule, l4_opt):
if rule.get(rule_port_name):
ports = rule[rule_port_name].split(':')
if rule_port_name == 'source_port':
port_prefix = 'src'
else:
port_prefix = 'dest'
l4_opt[port_prefix + '-port-start'] = ports[0]
if len(ports) == 2:
l4_opt[port_prefix + '-port-end'] = ports[1]
def _get_acl_rule_data(self, firewall):
"""Get ACL RESTAPI request data from firewall dictionary.
:return: ACL RESTAPI request data based on data from plugin.
:return: {} if there is any error.
"""
acl_rules_list = []
seq = 100
for rule in firewall['firewall_rule_list']:
if not rule['enabled']:
continue
ace_rule = {'sequence': str(seq)}
seq += 1
if rule.get('protocol'):
ace_rule['protocol'] = rule['protocol']
else:
ace_rule['protocol'] = 'all'
if rule['action'].lower() == 'allow':
ace_rule['action'] = 'permit'
else:
ace_rule['action'] = 'deny'
if rule.get('source_ip_address'):
ace_rule['source'] = rule['source_ip_address']
else:
ace_rule['source'] = 'any'
if rule.get('destination_ip_address'):
ace_rule['destination'] = rule['destination_ip_address']
else:
ace_rule['destination'] = 'any'
l4_opt = {}
self._get_acl_l4_port('source_port', rule, l4_opt)
self._get_acl_l4_port('destination_port', rule, l4_opt)
if l4_opt:
ace_rule['l4-options'] = l4_opt
acl_rules_list.append(ace_rule)
return {'rules': acl_rules_list}
def _get_interface_name_from_hosting_port(self, port):
vlan = port['hosting_info']['segmentation_id']
interface_type, interface_num = port[
'hosting_info']['hosting_port_name'].split(':')
offset = 0 if interface_type == 't1_p' else 1
interface_num = str(int(interface_num) * 2 + offset)
return 'GigabitEthernet%s.%s' % (interface_num, vlan)
def _post_acl_to_interfaces(self, firewall, csr, acl_id, status_data):
acl_interface_url = ACL_API_ACLID_IF % acl_id
for firewall_interface in firewall['vendor_ext']['if_list']:
if_name = self._get_interface_name_from_hosting_port(
firewall_interface['port'])
acl_interface_req = {
'if-id': if_name,
'direction': firewall_interface['direction']
}
LOG.debug("acl_interface_url %s", acl_interface_url)
csr.post_request(acl_interface_url, acl_interface_req)
if csr.status == requests.codes.CREATED:
status_data['if_list'].append(
{'port_id': firewall_interface['port']['id'],
'status': 'OK'})
else:
LOG.error(_LE("status %s"), csr.status)
status_data['if_list'].append(
{'port_id': firewall_interface['port']['id'],
'status': 'ERROR'})
def _delete_acl_on_interface(self, csr, acl_id,
csr_firewall_interface_list):
for interface in csr_firewall_interface_list:
my_api = ACL_API_ACLID_IFID_DIR % (
acl_id, interface['if-id'], interface['direction'])
csr.delete_request(my_api)
if csr.status != requests.codes.NO_CONTENT:
LOG.error(_LE("status %s"), csr.status)
def _get_acl_interface(self, csr, acl_id):
my_api = ACL_API_ACLID_IF % acl_id
response = csr.get_request(my_api)
if csr.status == requests.codes.OK:
return response['items']
LOG.error(_LE("status %s"), csr.status)
return ''
def _post_acl(self, csr, acl_data):
response = csr.post_request(ACL_API, acl_data)
if csr.status == requests.codes.CREATED:
return response[response.rfind('/') + 1:]
LOG.error(_LE("status %s"), csr.status)
return ''
def _delete_acl(self, csr, acl_id):
my_api = ACL_API_ACLID % acl_id
csr.delete_request(my_api)
if csr.status == requests.codes.NO_CONTENT:
return True
LOG.error(_LE("status %s"), csr.status)
return False
def _put_acl(self, csr, acl_id, acl_data):
my_api = ACL_API_ACLID % acl_id
csr.put_request(my_api, acl_data)
if csr.status == requests.codes.NO_CONTENT:
return True
LOG.error(_LE("status %s"), csr.status)
return False
def _create_firewall(self, firewall):
"""Create ACL and apply ACL to interfaces.
:param firewall: firewall dictionary
:return: True and status_data if OK
:return: False and status_data if there is an error
"""
LOG.debug("firewall %s", firewall)
if not self._validate_firewall_data(firewall):
return False, {}
if not self._validate_firewall_rule_data(firewall):
return False, {}
csr = self._get_csr_host(firewall['vendor_ext'])
acl_data = self._get_acl_rule_data(firewall)
LOG.debug("acl_data %s", acl_data)
acl_id = self._post_acl(csr, acl_data)
if not acl_id:
LOG.debug("No acl_id created, acl_data %s", acl_data)
return False, {}
LOG.debug("new ACL ID: %s", acl_id)
status_data = {
'fw_id': firewall['id'],
'acl_id': acl_id,
'if_list': []
}
if not firewall['admin_state_up']:
LOG.debug("status %s", status_data)
return True, status_data
# apply ACL to interfaces
self._post_acl_to_interfaces(firewall, csr, acl_id, status_data)
LOG.debug("status %s", status_data)
return True, status_data
def _delete_firewall(self, firewall):
"""Delete ACL.
:param firewall: firewall dictionary
:return: True if OK
:return: False if there is an error
"""
if not self._validate_firewall_data(firewall):
return False
acl_id = firewall['vendor_ext'].get('acl_id')
if not acl_id:
LOG.error(_LE("firewall (%s) has no acl_id"), firewall['id'])
return False
csr = self._get_csr_host(firewall['vendor_ext'])
return self._delete_acl(csr, acl_id)
def _update_firewall(self, firewall):
"""Update ACL and associated interfaces.
:param firewall: firewall dictionary
:return: True and status_data if OK
:return: False and {} if there is an error
"""
if not self._validate_firewall_data(firewall):
return False, {}
if not self._validate_firewall_rule_data(firewall):
return False, {}
acl_id = firewall['vendor_ext'].get('acl_id')
if not acl_id:
LOG.error(_LE("firewall (%s) has no acl_id"), firewall['id'])
return False, {}
csr = self._get_csr_host(firewall['vendor_ext'])
rest_acl_rules = self._get_acl_rule_data(firewall)
rest_acl_rules['acl-id'] = acl_id
# update ACL rules
response = self._put_acl(csr, acl_id, rest_acl_rules)
if not response:
return False, {}
status_data = {
'fw_id': firewall['id'],
'acl_id': acl_id,
'if_list': []
}
# update ACL interface
# get all interfaces with this acl_id
csr_fw_interface_list = self._get_acl_interface(csr, acl_id)
self._delete_acl_on_interface(csr, acl_id, csr_fw_interface_list)
if not firewall['admin_state_up']:
return True, status_data
self._post_acl_to_interfaces(firewall, csr, acl_id, status_data)
return True, status_data
def create_firewall(self, agent_mode, apply_list, firewall):
"""Create firewall on CSR."""
LOG.debug("create_firewall: firewall %s", firewall)
return self._create_firewall(firewall)
def delete_firewall(self, agent_mode, apply_list, firewall):
"""Delete firewall on CSR."""
LOG.debug("delete_firewall: firewall %s", firewall)
return self._delete_firewall(firewall)
def update_firewall(self, agent_mode, apply_list, firewall):
"""Update firewall on CSR."""
LOG.debug("update_firewall: firewall %s", firewall)
return self._update_firewall(firewall)
def apply_default_policy(self, agent_mode, apply_list, firewall):
# CSR firewall driver does not support this for now
LOG.debug("apply_default_policy")
neutron-fwaas-8.0.0/neutron_fwaas/services/firewall/drivers/cisco/__init__.py 0000664 0005670 0005671 00000000000 12701407720 030631 0 ustar jenkins jenkins 0000000 0000000 neutron-fwaas-8.0.0/neutron_fwaas/services/firewall/drivers/cisco/csr_firewall_svc_helper.py 0000664 0005670 0005671 00000023505 12701407720 033777 0 ustar jenkins jenkins 0000000 0000000 # Copyright 2014 Cisco Systems, Inc. All rights reserved.
#
# 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.
from networking_cisco.plugins.cisco.cfg_agent.service_helpers import (
service_helper)
from neutron.common import rpc as n_rpc
from neutron import context as n_context
from neutron.plugins.common import constants
from oslo_log import helpers as log_helpers
from oslo_log import log as logging
import oslo_messaging
from neutron_fwaas._i18n import _LE
from neutron_fwaas.services.firewall.drivers.cisco import csr_acl_driver
LOG = logging.getLogger(__name__)
CSR_FW_EVENT_Q_NAME = 'csr_fw_event_q'
CSR_FW_EVENT_CREATE = 'FW_EVENT_CREATE'
CSR_FW_EVENT_UPDATE = 'FW_EVENT_UPDATE'
CSR_FW_EVENT_DELETE = 'FW_EVENT_DELETE'
class CsrFirewalllPluginApi(object):
"""CsrFirewallServiceHelper (Agent) side of the ACL RPC API."""
@log_helpers.log_method_call
def __init__(self, topic, host):
self.host = host
target = oslo_messaging.Target(topic=topic, version='1.0')
self.client = n_rpc.get_client(target)
@log_helpers.log_method_call
def get_firewalls_for_device(self, context, **kwargs):
"""Get Firewalls with rules for a device from Plugin."""
cctxt = self.client.prepare()
return cctxt.call(context, 'get_firewalls_for_device', host=self.host)
@log_helpers.log_method_call
def get_firewalls_for_tenant(self, context, **kwargs):
"""Get Firewalls with rules for a tenant from the Plugin."""
cctxt = self.client.prepare()
return cctxt.call(context, 'get_firewalls_for_tenant', host=self.host)
@log_helpers.log_method_call
def get_tenants_with_firewalls(self, context, **kwargs):
"""Get Tenants that have Firewalls configured from plugin."""
cctxt = self.client.prepare()
return cctxt.call(context,
'get_tenants_with_firewalls', host=self.host)
@log_helpers.log_method_call
def set_firewall_status(self, context, fw_id, status, status_data=None):
"""Make a RPC to set the status of a firewall."""
cctxt = self.client.prepare()
return cctxt.call(context, 'set_firewall_status', host=self.host,
firewall_id=fw_id, status=status,
status_data=status_data)
def firewall_deleted(self, context, firewall_id):
"""Make a RPC to indicate that the firewall resources are deleted."""
cctxt = self.client.prepare()
return cctxt.call(context, 'firewall_deleted', host=self.host,
firewall_id=firewall_id)
class CsrFirewallServiceHelper(object):
@log_helpers.log_method_call
def __init__(self, host, conf, cfg_agent):
super(CsrFirewallServiceHelper, self).__init__()
self.conf = conf
self.cfg_agent = cfg_agent
self.fullsync = True
self.event_q = service_helper.QueueMixin()
self.fw_plugin_rpc = CsrFirewalllPluginApi(
'CISCO_FW_PLUGIN', conf.host)
self.topic = 'CISCO_FW'
self._setup_rpc()
self.acl_driver = csr_acl_driver.CsrAclDriver()
def _setup_rpc(self):
self.conn = n_rpc.create_connection()
self.endpoints = [self]
self.conn.create_consumer(self.topic,
self.endpoints, fanout=True)
self.conn.consume_in_threads()
### Notifications from Plugin ####
def create_firewall(self, context, firewall, host):
"""Handle Rpc from plugin to create a firewall."""
LOG.debug("create_firewall: firewall %s", firewall)
event_data = {'event': CSR_FW_EVENT_CREATE,
'context': context,
'firewall': firewall,
'host': host}
self.event_q.enqueue(CSR_FW_EVENT_Q_NAME, event_data)
def update_firewall(self, context, firewall, host):
"""Handle Rpc from plugin to update a firewall."""
LOG.debug("update_firewall: firewall %s", firewall)
event_data = {'event': CSR_FW_EVENT_UPDATE,
'context': context,
'firewall': firewall,
'host': host}
self.event_q.enqueue(CSR_FW_EVENT_Q_NAME, event_data)
def delete_firewall(self, context, firewall, host):
"""Handle Rpc from plugin to delete a firewall."""
LOG.debug("delete_firewall: firewall %s", firewall)
event_data = {'event': CSR_FW_EVENT_DELETE,
'context': context,
'firewall': firewall,
'host': host}
self.event_q.enqueue(CSR_FW_EVENT_Q_NAME, event_data)
def _invoke_firewall_driver(self, context, firewall, func_name):
LOG.debug("_invoke_firewall_driver: %s", func_name)
try:
if func_name == 'delete_firewall':
return_code = self.acl_driver.__getattribute__(func_name)(
None, None, firewall)
if not return_code:
LOG.debug("firewall %s", firewall['id'])
self.fw_plugin_rpc.set_firewall_status(
context, firewall['id'], constants.ERROR)
else:
self.fw_plugin_rpc.firewall_deleted(
context, firewall['id'])
else:
return_code, status = self.acl_driver.__getattribute__(
func_name)(None, None, firewall)
if not return_code:
LOG.debug("firewall %s", firewall['id'])
self.fw_plugin_rpc.set_firewall_status(
context, firewall['id'], constants.ERROR)
else:
LOG.debug("status %s", status)
self.fw_plugin_rpc.set_firewall_status(
context, firewall['id'], constants.ACTIVE, status)
except Exception:
LOG.debug("_invoke_firewall_driver: PRC failure")
self.fullsync = True
def _process_firewall_pending_op(self, context, firewall_list):
for firewall in firewall_list:
firewall_status = firewall['status']
if firewall_status == 'PENDING_CREATE':
self._invoke_firewall_driver(
context, firewall, 'create_firewall')
elif firewall_status == 'PENDING_UPDATE':
self._invoke_firewall_driver(
context, firewall, 'update_firewall')
elif firewall_status == 'PENDING_DELETE':
self._invoke_firewall_driver(
context, firewall, 'delete_firewall')
def _process_fullsync(self):
LOG.debug("_process_fullsync")
try:
context = n_context.get_admin_context()
tenants = self.fw_plugin_rpc.get_tenants_with_firewalls(
context)
LOG.debug("tenants with firewall: %s", tenants)
for tenant_id in tenants:
ctx = n_context.Context('', tenant_id)
firewall_list = self.fw_plugin_rpc.get_firewalls_for_tenant(
ctx)
self._process_firewall_pending_op(ctx, firewall_list)
except Exception:
LOG.debug("_process_fullsync: RPC failure")
self.fullsync = True
def _process_devices(self, device_ids):
LOG.debug("_process_devices: device_ids %s", device_ids)
try:
for device_id in device_ids:
ctx = n_context.Context('', device_id)
firewall_list = self.fw_plugin_rpc.get_firewalls_for_device(
ctx)
self._process_firewall_pending_op(ctx, firewall_list)
except Exception:
LOG.debug("_process_devices: RPC failure")
self.fullsync = True
def _process_event_q(self):
while True:
try:
event_data = self.event_q.dequeue(CSR_FW_EVENT_Q_NAME)
if not event_data:
return
except ValueError:
LOG.debug("_process_event_q: no queue yet")
return
LOG.debug("_process_event_q: event_data %s", event_data)
event = event_data['event']
context = event_data['context']
firewall = event_data['firewall']
if event == CSR_FW_EVENT_CREATE:
self._invoke_firewall_driver(
context, firewall, 'create_firewall')
elif event == CSR_FW_EVENT_UPDATE:
self._invoke_firewall_driver(
context, firewall, 'update_firewall')
elif event == CSR_FW_EVENT_DELETE:
self._invoke_firewall_driver(
context, firewall, 'delete_firewall')
else:
LOG.error(_LE("invalid event %s"), event)
def process_service(self, device_ids=None, removed_devices_info=None):
try:
if self.fullsync:
self.fullsync = False
self._process_fullsync()
else:
if device_ids:
self._process_devices(device_ids)
if removed_devices_info:
LOG.debug("process_service: removed_devices_info %s",
removed_devices_info)
# do nothing for now
else:
self._process_event_q()
except Exception:
LOG.exception(_LE('process_service exception ERROR'))
neutron-fwaas-8.0.0/neutron_fwaas/services/firewall/drivers/__init__.py 0000664 0005670 0005671 00000000000 12701407720 027531 0 ustar jenkins jenkins 0000000 0000000 neutron-fwaas-8.0.0/neutron_fwaas/services/firewall/drivers/vyatta/ 0000775 0005670 0005671 00000000000 12701410073 026735 5 ustar jenkins jenkins 0000000 0000000 neutron-fwaas-8.0.0/neutron_fwaas/services/firewall/drivers/vyatta/__init__.py 0000664 0005670 0005671 00000000000 12701407720 031041 0 ustar jenkins jenkins 0000000 0000000 neutron-fwaas-8.0.0/neutron_fwaas/services/firewall/drivers/vyatta/vyatta_fwaas.py 0000664 0005670 0005671 00000016034 12701407720 032011 0 ustar jenkins jenkins 0000000 0000000 # Copyright 2015 Brocade Communications System, Inc.
# All Rights Reserved.
#
# 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.
from networking_brocade.vyatta.common import config as vyatta_config
from networking_brocade.vyatta.vrouter import client as vyatta_client
from neutron import context as neutron_context
from novaclient import client as nova_client
from oslo_log import log as logging
from six.moves.urllib import parse
from neutron_fwaas._i18n import _LW
from neutron_fwaas.services.firewall.agents.vyatta import vyatta_utils
from neutron_fwaas.services.firewall.drivers import fwaas_base
LOG = logging.getLogger(__name__)
FW_NAME = 'firewall/name/{0}'
FW_DESCRIPTION = 'firewall/name/{0}/description/{1}'
FW_ESTABLISHED_ACCEPT = 'firewall/state-policy/established/action/accept'
FW_RELATED_ACCEPT = 'firewall/state-policy/related/action/accept'
FW_RULE_DESCRIPTION = 'firewall/name/{0}/rule/{1}/description/{2}'
FW_RULE_PROTOCOL = 'firewall/name/{0}/rule/{1}/protocol/{2}'
FW_RULE_SRC_PORT = 'firewall/name/{0}/rule/{1}/source/port/{2}'
FW_RULE_DEST_PORT = 'firewall/name/{0}/rule/{1}/destination/port/{2}'
FW_RULE_SRC_ADDR = 'firewall/name/{0}/rule/{1}/source/address/{2}'
FW_RULE_DEST_ADDR = 'firewall/name/{0}/rule/{1}/destination/address/{2}'
FW_RULE_ACTION = 'firewall/name/{0}/rule/{1}/action/{2}'
NOVACLIENT_VERSION = '2'
class VyattaFirewallDriver(fwaas_base.FwaasDriverBase):
def __init__(self):
LOG.debug("Vyatta vRouter Fwaas:: Initializing fwaas driver")
compute_client = nova_client.Client(
NOVACLIENT_VERSION,
vyatta_config.VROUTER.tenant_admin_name,
vyatta_config.VROUTER.tenant_admin_password,
auth_url=vyatta_config.CONF.nova_admin_auth_url,
service_type="compute",
tenant_id=vyatta_config.VROUTER.tenant_id)
self._vyatta_clients_pool = vyatta_client.ClientsPool(compute_client)
def create_firewall(self, agent_mode, apply_list, firewall):
LOG.debug('Vyatta vRouter Fwaas::Create_firewall (%s)', firewall)
return self.update_firewall(agent_mode, apply_list, firewall)
def update_firewall(self, agent_mode, apply_list, firewall):
LOG.debug('Vyatta vRouter Fwaas::Update_firewall (%s)', firewall)
if firewall['admin_state_up']:
return self._update_firewall(apply_list, firewall)
else:
return self.apply_default_policy(agent_mode, apply_list, firewall)
def delete_firewall(self, agent_mode, apply_list, firewall):
LOG.debug('Vyatta vRouter Fwaas::Delete_firewall (%s)', firewall)
return self.apply_default_policy(agent_mode, apply_list, firewall)
def apply_default_policy(self, agent_mode, apply_list, firewall):
LOG.debug('Vyatta vRouter Fwaas::apply_default_policy (%s)',
firewall)
for ri in apply_list:
self._delete_firewall(ri, firewall)
return True
def _update_firewall(self, apply_list, firewall):
LOG.debug("Updating firewall (%s)", firewall['id'])
for ri in apply_list:
self._delete_firewall(ri, firewall)
self._setup_firewall(ri, firewall)
return True
def _setup_firewall(self, ri, fw):
client = self._get_vyatta_client(ri.router)
fw_cmd_list = []
# Create firewall
fw_name = vyatta_utils.get_firewall_name(ri, fw)
fw_cmd_list.append(
vyatta_client.SetCmd(
FW_NAME.format(parse.quote_plus(fw_name))))
if fw.get('description'):
fw_cmd_list.append(vyatta_client.SetCmd(
FW_DESCRIPTION.format(
parse.quote_plus(fw_name),
parse.quote_plus(fw['description']))))
# Set firewall state policy
fw_cmd_list.append(vyatta_client.SetCmd(FW_ESTABLISHED_ACCEPT))
fw_cmd_list.append(vyatta_client.SetCmd(FW_RELATED_ACCEPT))
# Create firewall rules
rule_num = 0
for rule in fw['firewall_rule_list']:
if not rule['enabled']:
continue
if rule['ip_version'] == 4:
rule_num += 1
fw_cmd_list += self._set_firewall_rule(fw_name, rule_num, rule)
else:
LOG.warning(_LW("IPv6 rules are not supported."))
# Configure router zones
zone_cmd_list = vyatta_utils.get_zone_cmds(client, ri, fw_name)
client.exec_cmd_batch(fw_cmd_list + zone_cmd_list)
def _delete_firewall(self, ri, fw):
client = self._get_vyatta_client(ri.router)
cmd_list = []
# Delete zones
cmd_list.append(vyatta_client.DeleteCmd("zone-policy"))
# Delete firewall
fw_name = vyatta_utils.get_firewall_name(ri, fw)
cmd_list.append(vyatta_client.DeleteCmd(
FW_NAME.format(parse.quote_plus(fw_name))))
# Delete firewall state policy
cmd_list.append(vyatta_client.DeleteCmd("firewall/state-policy"))
client.exec_cmd_batch(cmd_list)
def _set_firewall_rule(self, fw_name, rule_num, rule):
cmd_list = []
if 'description' in rule and len(rule['description']) > 0:
cmd_list.append(vyatta_client.SetCmd(
FW_RULE_DESCRIPTION.format(
parse.quote_plus(fw_name), rule_num,
parse.quote_plus(rule['description']))))
rules = [
('protocol', FW_RULE_PROTOCOL),
('source_port', FW_RULE_SRC_PORT),
('destination_port', FW_RULE_DEST_PORT),
('source_ip_address', FW_RULE_SRC_ADDR),
('destination_ip_address', FW_RULE_DEST_ADDR),
]
for key, url in rules:
field = rule.get(key)
if field is None:
continue
# For safety and extensibility we need to use quote_plus
# for all data retrieved from external sources.
cmd_list.append(vyatta_client.SetCmd(
url.format(
parse.quote_plus(fw_name), rule_num,
parse.quote_plus(field))))
if 'action' in rule:
if rule['action'] == 'allow':
action = 'accept'
else:
action = 'drop'
cmd_list.append(vyatta_client.SetCmd(
FW_RULE_ACTION.format(
parse.quote_plus(fw_name), rule_num,
action)))
return cmd_list
def _get_vyatta_client(self, router):
ctx = neutron_context.Context(None, router['tenant_id'])
return self._vyatta_clients_pool.get_by_db_lookup(router['id'], ctx)
neutron-fwaas-8.0.0/neutron_fwaas/services/firewall/drivers/vyatta/README.rst 0000664 0005670 0005671 00000000542 12701407720 030432 0 ustar jenkins jenkins 0000000 0000000 Brocade Firewall as a Service Driver
* For more information, refer to:
https://wiki.openstack.org/wiki/Brocade_Vyatta_Firewall_driver
* For information on Brocade Vyatta CI, refer to:
https://wiki.openstack.org/wiki/ThirdPartySystems/Brocade_Vyatta_CI
* Brocade Vyatta CI contact:
- DL-GRP-VYATTA-OSS@Brocade.com
- vjayara@Brocade.com
neutron-fwaas-8.0.0/neutron_fwaas/services/firewall/agents/ 0000775 0005670 0005671 00000000000 12701410073 025230 5 ustar jenkins jenkins 0000000 0000000 neutron-fwaas-8.0.0/neutron_fwaas/services/firewall/agents/firewall_agent_api.py 0000664 0005670 0005671 00000004661 12701407720 031432 0 ustar jenkins jenkins 0000000 0000000 # Copyright (c) 2013 OpenStack Foundation
# All Rights Reserved.
#
# 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.
from neutron.common import rpc as n_rpc
from oslo_config import cfg
import oslo_messaging
from neutron_fwaas._i18n import _
FWaaSOpts = [
cfg.StrOpt(
'driver',
default='',
help=_("Name of the FWaaS Driver")),
cfg.BoolOpt(
'enabled',
default=False,
help=_("Enable FWaaS")),
]
cfg.CONF.register_opts(FWaaSOpts, 'fwaas')
class FWaaSPluginApiMixin(object):
"""Agent side of the FWaaS agent to FWaaS Plugin RPC API."""
def __init__(self, topic, host):
self.host = host
target = oslo_messaging.Target(topic=topic, version='1.0')
self.client = n_rpc.get_client(target)
def set_firewall_status(self, context, firewall_id, status):
"""Make a RPC to set the status of a firewall."""
cctxt = self.client.prepare()
return cctxt.call(context, 'set_firewall_status', host=self.host,
firewall_id=firewall_id, status=status)
def firewall_deleted(self, context, firewall_id):
"""Make a RPC to indicate that the firewall resources are deleted."""
cctxt = self.client.prepare()
return cctxt.call(context, 'firewall_deleted', host=self.host,
firewall_id=firewall_id)
class FWaaSAgentRpcCallbackMixin(object):
"""Mixin for FWaaS agent Implementations."""
def __init__(self, host):
super(FWaaSAgentRpcCallbackMixin, self).__init__(host)
def create_firewall(self, context, firewall, host):
"""Handle RPC cast from plugin to create a firewall."""
pass
def update_firewall(self, context, firewall, host):
"""Handle RPC cast from plugin to update a firewall."""
pass
def delete_firewall(self, context, firewall, host):
"""Handle RPC cast from plugin to delete a firewall."""
pass
neutron-fwaas-8.0.0/neutron_fwaas/services/firewall/agents/l3reference/ 0000775 0005670 0005671 00000000000 12701410073 027425 5 ustar jenkins jenkins 0000000 0000000 neutron-fwaas-8.0.0/neutron_fwaas/services/firewall/agents/l3reference/firewall_l3_agent.py 0000664 0005670 0005671 00000041733 12701407720 033375 0 ustar jenkins jenkins 0000000 0000000 # Copyright (c) 2013 OpenStack Foundation.
# All Rights Reserved.
#
# 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.
from neutron.agent.linux import ip_lib
from neutron import context
from neutron.plugins.common import constants as n_const
from oslo_config import cfg
from oslo_log import helpers as log_helpers
from oslo_log import log as logging
from neutron_fwaas._i18n import _, _LE
from neutron_fwaas.common import fwaas_constants as f_const
from neutron_fwaas.extensions import firewall as fw_ext
from neutron_fwaas.services.firewall.agents import firewall_agent_api as api
from neutron_fwaas.services.firewall.agents import firewall_service
LOG = logging.getLogger(__name__)
class FWaaSL3PluginApi(api.FWaaSPluginApiMixin):
"""Agent side of the FWaaS agent to FWaaS Plugin RPC API."""
def __init__(self, topic, host):
super(FWaaSL3PluginApi, self).__init__(topic, host)
def get_firewalls_for_tenant(self, context, **kwargs):
"""Get the Firewalls with rules from the Plugin to send to driver."""
LOG.debug("Retrieve Firewall with rules from Plugin")
cctxt = self.client.prepare()
return cctxt.call(context, 'get_firewalls_for_tenant', host=self.host)
def get_tenants_with_firewalls(self, context, **kwargs):
"""Get all Tenants that have Firewalls configured from plugin."""
LOG.debug("Retrieve Tenants with Firewalls configured from Plugin")
cctxt = self.client.prepare()
return cctxt.call(context,
'get_tenants_with_firewalls', host=self.host)
class FWaaSL3AgentRpcCallback(api.FWaaSAgentRpcCallbackMixin):
"""FWaaS Agent support to be used by Neutron L3 agent."""
def __init__(self, conf):
LOG.debug("Initializing firewall agent")
self.conf = conf
self.fwaas_enabled = cfg.CONF.fwaas.enabled
# None means l3-agent has no information on the server
# configuration due to the lack of RPC support.
if self.neutron_service_plugins is not None:
fwaas_plugin_configured = (n_const.FIREWALL
in self.neutron_service_plugins)
if fwaas_plugin_configured and not self.fwaas_enabled:
msg = _("FWaaS plugin is configured in the server side, but "
"FWaaS is disabled in L3-agent.")
LOG.error(msg)
raise SystemExit(1)
self.fwaas_enabled = self.fwaas_enabled and fwaas_plugin_configured
if self.fwaas_enabled:
# NOTE: Temp location for creating service and loading driver
self.fw_service = firewall_service.FirewallService()
self.fwaas_driver = self.fw_service.load_device_drivers()
self.services_sync_needed = False
# setup RPC to msg fwaas plugin
self.fwplugin_rpc = FWaaSL3PluginApi(f_const.FIREWALL_PLUGIN,
conf.host)
super(FWaaSL3AgentRpcCallback, self).__init__(host=conf.host)
def _has_router_insertion_fields(self, fw):
return 'add-router-ids' in fw
def _get_router_ids_for_fw(self, context, fw, to_delete=False):
"""Return the router_ids either from fw dict or tenant routers."""
if self._has_router_insertion_fields(fw):
# it is a new version of plugin
return (fw['del-router-ids'] if to_delete
else fw['add-router-ids'])
else:
# we are in a upgrade and msg from older version of plugin
try:
routers = self.plugin_rpc.get_routers(context)
except Exception:
LOG.exception(
_LE("FWaaS RPC failure in _get_router_ids_for_fw "
"for firewall: %(fwid)s"),
{'fwid': fw['id']})
self.services_sync_needed = True
return [
router['id']
for router in routers
if router['tenant_id'] == fw['tenant_id']]
def _get_router_info_list_for_tenant(self, router_ids, tenant_id):
"""Returns the list of router info objects on which to apply the fw."""
root_ip = ip_lib.IPWrapper()
local_ns_list = root_ip.get_namespaces()
router_info_list = []
# Pick up namespaces for Tenant Routers
for rid in router_ids:
# for routers without an interface - get_routers returns
# the router - but this is not yet populated in router_info
if rid not in self.router_info:
continue
router_ns = self.router_info[rid].ns_name
if router_ns in local_ns_list:
router_info_list.append(self.router_info[rid])
return router_info_list
def _invoke_driver_for_sync_from_plugin(self, ctx, router_info_list, fw):
"""Invoke the delete driver method for status of PENDING_DELETE and
update method for all other status to (re)apply on driver which is
Idempotent.
"""
if fw['status'] == n_const.PENDING_DELETE:
try:
self.fwaas_driver.delete_firewall(
self.conf.agent_mode,
router_info_list,
fw)
self.fwplugin_rpc.firewall_deleted(
ctx,
fw['id'])
except fw_ext.FirewallInternalDriverError:
LOG.error(_LE("Firewall Driver Error on fw state %(fwmsg)s "
"for fw: %(fwid)s"),
{'fwmsg': fw['status'], 'fwid': fw['id']})
self.fwplugin_rpc.set_firewall_status(
ctx,
fw['id'],
n_const.ERROR)
else:
# PENDING_UPDATE, PENDING_CREATE, ...
try:
self.fwaas_driver.update_firewall(
self.conf.agent_mode,
router_info_list,
fw)
if fw['admin_state_up']:
status = n_const.ACTIVE
else:
status = n_const.DOWN
except fw_ext.FirewallInternalDriverError:
LOG.error(_LE("Firewall Driver Error on fw state %(fwmsg)s "
"for fw: %(fwid)s"),
{'fwmsg': fw['status'], 'fwid': fw['id']})
status = n_const.ERROR
self.fwplugin_rpc.set_firewall_status(
ctx,
fw['id'],
status)
def _process_router_add(self, ri):
"""On router add, get fw with rules from plugin and update driver."""
LOG.debug("Process router add, router_id: '%s'", ri.router['id'])
router_ids = ri.router['id']
router_info_list = self._get_router_info_list_for_tenant(
[router_ids],
ri.router['tenant_id'])
if router_info_list:
# Get the firewall with rules
# for the tenant the router is on.
ctx = context.Context('', ri.router['tenant_id'])
fw_list = self.fwplugin_rpc.get_firewalls_for_tenant(ctx)
for fw in fw_list:
if self._has_router_insertion_fields(fw):
# if router extension present apply only if router in fw
if (not (router_ids in fw['add-router-ids']) and
not (router_ids in fw['del-router-ids'])):
continue
self._invoke_driver_for_sync_from_plugin(
ctx,
router_info_list,
fw)
# router can be present only on one fw
return
def process_router_add(self, ri):
"""On router add, get fw with rules from plugin and update driver.
Handles agent restart, when a router is added, query the plugin to
check if this router is in the router list for any firewall. If so
install firewall rules on this router.
"""
# avoid msg to plugin when fwaas is not configured
if not self.fwaas_enabled:
return
try:
# TODO(sridar): as per discussion with pc_m, we may want to hook
# this up to the l3 agent observer notification
self._process_router_add(ri)
except Exception:
LOG.exception(
_LE("FWaaS RPC info call failed for '%s'."),
ri.router['id'])
self.services_sync_needed = True
def process_services_sync(self, ctx):
if not self.services_sync_needed:
return
"""On RPC issues sync with plugin and apply the sync data."""
# avoid msg to plugin when fwaas is not configured
if not self.fwaas_enabled:
return
try:
# get the list of tenants with firewalls configured
# from the plugin
tenant_ids = self.fwplugin_rpc.get_tenants_with_firewalls(ctx)
LOG.debug("Tenants with Firewalls: '%s'", tenant_ids)
for tenant_id in tenant_ids:
ctx = context.Context('', tenant_id)
fw_list = self.fwplugin_rpc.get_firewalls_for_tenant(ctx)
for fw in fw_list:
if fw['status'] == n_const.PENDING_DELETE:
self.delete_firewall(ctx, fw, self.host)
# no need to apply sync data for ACTIVE fw
elif fw['status'] != n_const.ACTIVE:
self.update_firewall(ctx, fw, self.host)
self.services_sync_needed = False
except Exception:
LOG.exception(_LE("Failed fwaas process services sync"))
self.services_sync_needed = True
@log_helpers.log_method_call
def create_firewall(self, context, firewall, host):
"""Handle Rpc from plugin to create a firewall."""
router_ids = self._get_router_ids_for_fw(context, firewall)
if not router_ids:
return
router_info_list = self._get_router_info_list_for_tenant(
router_ids,
firewall['tenant_id'])
LOG.debug("Create: Add firewall on Router List: '%s'",
[ri.router['id'] for ri in router_info_list])
# call into the driver
try:
self.fwaas_driver.create_firewall(
self.conf.agent_mode,
router_info_list,
firewall)
if firewall['admin_state_up']:
status = n_const.ACTIVE
else:
status = n_const.DOWN
except fw_ext.FirewallInternalDriverError:
LOG.error(_LE("Firewall Driver Error for create_firewall "
"for firewall: %(fwid)s"),
{'fwid': firewall['id']})
status = n_const.ERROR
try:
# send status back to plugin
self.fwplugin_rpc.set_firewall_status(
context,
firewall['id'],
status)
except Exception:
LOG.exception(
_LE("FWaaS RPC failure in create_firewall "
"for firewall: %(fwid)s"),
{'fwid': firewall['id']})
self.services_sync_needed = True
@log_helpers.log_method_call
def update_firewall(self, context, firewall, host):
"""Handle Rpc from plugin to update a firewall."""
status = ""
if self._has_router_insertion_fields(firewall):
# with the router_ids extension, we may need to delete and add
# based on the list of routers. On the older version, we just
# update (add) all routers on the tenant - delete not needed.
router_ids = self._get_router_ids_for_fw(
context, firewall, to_delete=True)
if router_ids:
router_info_list = self._get_router_info_list_for_tenant(
router_ids,
firewall['tenant_id'])
# remove the firewall from this set of routers
# but no ack sent yet, check if we need to add
LOG.debug("Update: Delete firewall on Router List: '%s'",
[ri.router['id'] for ri in router_info_list])
try:
self.fwaas_driver.delete_firewall(
self.conf.agent_mode,
router_info_list,
firewall)
if firewall['last-router']:
status = n_const.INACTIVE
elif firewall['admin_state_up']:
status = n_const.ACTIVE
else:
status = n_const.DOWN
except fw_ext.FirewallInternalDriverError:
LOG.error(_LE("Firewall Driver Error for "
"update_firewall for firewall: "
"%(fwid)s"),
{'fwid': firewall['id']})
status = n_const.ERROR
# handle the add router and/or rule, policy, firewall
# attribute updates
if status not in (n_const.ERROR, n_const.INACTIVE):
router_ids = self._get_router_ids_for_fw(context, firewall)
if router_ids or firewall['router_ids']:
router_info_list = self._get_router_info_list_for_tenant(
router_ids + firewall['router_ids'],
firewall['tenant_id'])
LOG.debug("Update: Add firewall on Router List: '%s'",
[ri.router['id'] for ri in router_info_list])
# call into the driver
try:
self.fwaas_driver.update_firewall(
self.conf.agent_mode,
router_info_list,
firewall)
if firewall['admin_state_up']:
status = n_const.ACTIVE
else:
status = n_const.DOWN
except fw_ext.FirewallInternalDriverError:
LOG.error(_LE("Firewall Driver Error for "
"update_firewall for firewall: "
"%(fwid)s"),
{'fwid': firewall['id']})
status = n_const.ERROR
else:
status = n_const.INACTIVE
try:
# send status back to plugin
self.fwplugin_rpc.set_firewall_status(
context,
firewall['id'],
status)
except Exception:
LOG.exception(
_LE("FWaaS RPC failure in update_firewall "
"for firewall: %(fwid)s"),
{'fwid': firewall['id']})
self.services_sync_needed = True
@log_helpers.log_method_call
def delete_firewall(self, context, firewall, host):
"""Handle Rpc from plugin to delete a firewall."""
router_ids = self._get_router_ids_for_fw(
context, firewall, to_delete=True)
if router_ids:
router_info_list = self._get_router_info_list_for_tenant(
router_ids,
firewall['tenant_id'])
LOG.debug(
"Delete firewall %(fw)s on routers: '%(routers)s'"
% {'fw': firewall['id'],
'routers': [ri.router['id'] for ri in router_info_list]})
# call into the driver
try:
self.fwaas_driver.delete_firewall(
self.conf.agent_mode,
router_info_list,
firewall)
if firewall['admin_state_up']:
status = n_const.ACTIVE
else:
status = n_const.DOWN
except fw_ext.FirewallInternalDriverError:
LOG.error(_LE("Firewall Driver Error for delete_firewall "
"for firewall: %(fwid)s"),
{'fwid': firewall['id']})
status = n_const.ERROR
try:
# send status back to plugin
if status in [n_const.ACTIVE, n_const.DOWN]:
self.fwplugin_rpc.firewall_deleted(context, firewall['id'])
else:
self.fwplugin_rpc.set_firewall_status(
context,
firewall['id'],
status)
except Exception:
LOG.exception(
_LE("FWaaS RPC failure in delete_firewall "
"for firewall: %(fwid)s"),
{'fwid': firewall['id']})
self.services_sync_needed = True
neutron-fwaas-8.0.0/neutron_fwaas/services/firewall/agents/l3reference/__init__.py 0000664 0005670 0005671 00000000000 12701407720 031531 0 ustar jenkins jenkins 0000000 0000000 neutron-fwaas-8.0.0/neutron_fwaas/services/firewall/agents/varmour/ 0000775 0005670 0005671 00000000000 12701410073 026723 5 ustar jenkins jenkins 0000000 0000000 neutron-fwaas-8.0.0/neutron_fwaas/services/firewall/agents/varmour/varmour_api.py 0000775 0005670 0005671 00000011411 12701407720 031627 0 ustar jenkins jenkins 0000000 0000000 # Copyright 2013 vArmour Networks Inc.
# All Rights Reserved.
#
# 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.
import base64
import httplib2
from oslo_config import cfg
from oslo_log import log as logging
from oslo_serialization import jsonutils
from neutron_fwaas._i18n import _, _LE
from neutron_fwaas.services.firewall.agents.varmour \
import varmour_utils as va_utils
OPTS = [
cfg.StrOpt('director', default='localhost',
help=_("vArmour director ip")),
cfg.StrOpt('director_port', default='443',
help=_("vArmour director port")),
cfg.StrOpt('username', default='varmour',
help=_("vArmour director username")),
cfg.StrOpt('password', default='varmour', secret=True,
help=_("vArmour director password")), ]
cfg.CONF.register_opts(OPTS, "vArmour")
LOG = logging.getLogger(__name__)
REST_URL_PREFIX = '/api/v1.0'
class vArmourAPIException(Exception):
message = _("An unknown exception.")
def __init__(self, **kwargs):
try:
self.err = self.message % kwargs
except Exception:
self.err = self.message
def __str__(self):
return self.err
class AuthenticationFailure(vArmourAPIException):
message = _("Invalid login credential.")
class vArmourRestAPI(object):
def __init__(self):
LOG.debug('vArmourRestAPI: started')
self.user = cfg.CONF.vArmour.username
self.passwd = cfg.CONF.vArmour.password
self.server = cfg.CONF.vArmour.director
self.port = cfg.CONF.vArmour.director_port
self.timeout = 3
self.key = ''
def auth(self):
headers = {}
enc = base64.b64encode(self.user + ':' + self.passwd)
headers['Authorization'] = 'Basic ' + enc
resp = self.rest_api('POST', va_utils.REST_URL_AUTH, None, headers)
if resp and resp['status'] == 200:
self.key = resp['body']['auth']
return True
else:
raise AuthenticationFailure()
def commit(self):
self.rest_api('POST', va_utils.REST_URL_COMMIT)
def rest_api(self, method, url, body=None, headers=None):
url = REST_URL_PREFIX + url
if body:
body_data = jsonutils.dumps(body)
else:
body_data = ''
if not headers:
headers = {}
enc = base64.b64encode('%s:%s' % (self.user, self.key))
headers['Authorization'] = 'Basic ' + enc
LOG.debug("vArmourRestAPI: %(server)s %(port)s",
{'server': self.server, 'port': self.port})
try:
action = "https://" + self.server + ":" + self.port + url
LOG.debug("vArmourRestAPI Sending: "
"%(method)s %(action)s %(headers)s %(body_data)s",
{'method': method, 'action': action,
'headers': headers, 'body_data': body_data})
h = httplib2.Http(timeout=3,
disable_ssl_certificate_validation=True)
resp, resp_str = h.request(action, method,
body=body_data,
headers=headers)
LOG.debug("vArmourRestAPI Response: %(status)s %(resp_str)s",
{'status': resp.status, 'resp_str': resp_str})
if resp.status == 200:
return {'status': resp.status,
'reason': resp.reason,
'body': jsonutils.loads(resp_str)}
except Exception:
LOG.error(_LE('vArmourRestAPI: Could not establish HTTP '
'connection'))
def del_cfg_objs(self, url, prefix):
resp = self.rest_api('GET', url)
if resp and resp['status'] == 200:
olist = resp['body']['response']
if not olist:
return
for o in olist:
if o.startswith(prefix):
self.rest_api('DELETE', url + '/"name:%s"' % o)
self.commit()
def count_cfg_objs(self, url, prefix):
count = 0
resp = self.rest_api('GET', url)
if resp and resp['status'] == 200:
for o in resp['body']['response']:
if o.startswith(prefix):
count += 1
return count
neutron-fwaas-8.0.0/neutron_fwaas/services/firewall/agents/varmour/__init__.py 0000775 0005670 0005671 00000000000 12701407720 031032 0 ustar jenkins jenkins 0000000 0000000 neutron-fwaas-8.0.0/neutron_fwaas/services/firewall/agents/varmour/varmour_router.py 0000775 0005670 0005671 00000031454 12701407720 032407 0 ustar jenkins jenkins 0000000 0000000 # Copyright 2013 vArmour Networks Inc.
# All Rights Reserved.
#
# 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.
import sys
import eventlet
eventlet.monkey_patch()
import netaddr
from neutron.agent.common import config
from neutron.agent.l3 import agent
from neutron.agent.l3 import config as l3_config
from neutron.agent.l3 import ha
from neutron.agent.l3 import router_info
from neutron.agent.linux import external_process
from neutron.agent.linux import interface
from neutron.agent.linux import ip_lib
from neutron.common import config as common_config
from neutron import service as neutron_service
from neutron_lib import constants as l3_constants
from oslo_config import cfg
from oslo_log import log as logging
from oslo_service import service
from neutron_fwaas._i18n import _, _LW
from neutron_fwaas.common import fwaas_constants as f_const
from neutron_fwaas.services.firewall.agents.l3reference \
import firewall_l3_agent
from neutron_fwaas.services.firewall.agents.varmour import varmour_api
from neutron_fwaas.services.firewall.agents.varmour \
import varmour_utils as va_utils
LOG = logging.getLogger(__name__)
class vArmourL3NATAgent(agent.L3NATAgent,
firewall_l3_agent.FWaaSL3AgentRpcCallback):
def __init__(self, host, conf=None):
LOG.debug('vArmourL3NATAgent: __init__')
self.rest = varmour_api.vArmourRestAPI()
super(vArmourL3NATAgent, self).__init__(host, conf)
def _destroy_router_namespace(self, namespace):
return
def _create_router_namespace(self, ri):
return
def _router_added(self, router_id, router):
LOG.debug("_router_added: %s", router_id)
ri = router_info.RouterInfo(router_id=router_id, router=router,
agent_conf=self.conf,
interface_driver=self.driver)
self.router_info[router_id] = ri
super(vArmourL3NATAgent, self).process_router_add(ri)
def _router_removed(self, router_id):
LOG.debug("_router_removed: %s", router_id)
ri = self.router_info[router_id]
if ri:
ri.router['gw_port'] = None
ri.router[l3_constants.INTERFACE_KEY] = []
ri.router[l3_constants.FLOATINGIP_KEY] = []
self.process_router(ri)
name = va_utils.get_snat_rule_name(ri)
self.rest.del_cfg_objs(va_utils.REST_URL_CONF_NAT_RULE, name)
name = va_utils.get_dnat_rule_name(ri)
self.rest.del_cfg_objs(va_utils.REST_URL_CONF_NAT_RULE, name)
name = va_utils.get_trusted_zone_name(ri)
self._va_unset_zone_interfaces(name, True)
name = va_utils.get_untrusted_zone_name(ri)
self._va_unset_zone_interfaces(name, True)
del self.router_info[router_id]
def _spawn_metadata_proxy(self, router_id, ns_name):
return
def _destroy_metadata_proxy(self, router_id, ns_name):
return
def _set_subnet_info(self, port):
ips = port['fixed_ips']
if not ips:
raise Exception(_("Router port %s has no IP address") % port['id'])
if len(ips) > 1:
LOG.warning(_LW("Ignoring multiple IPs on router port %s"),
port['id'])
prefixlen = netaddr.IPNetwork(port['subnet']['cidr']).prefixlen
port['ip_cidr'] = "%s/%s" % (ips[0]['ip_address'], prefixlen)
def _va_unset_zone_interfaces(self, zone_name, remove_zone=False):
# return True if zone exists; otherwise, return False
LOG.debug("_va_unset_zone_interfaces: %s", zone_name)
resp = self.rest.rest_api('GET', va_utils.REST_URL_CONF_ZONE)
if resp and resp['status'] == 200:
zlist = resp['body']['response']
for zn in zlist:
if zn == zone_name:
commit = False
if 'interface' in zlist[zn]:
for intf in zlist[zn]['interface']:
self.rest.rest_api('DELETE',
va_utils.REST_URL_CONF +
va_utils.REST_ZONE_NAME % zn +
va_utils.REST_INTF_NAME % intf)
commit = True
if remove_zone:
self.rest.rest_api('DELETE',
va_utils.REST_URL_CONF +
va_utils.REST_ZONE_NAME % zn)
commit = True
if commit:
self.rest.commit()
return True
return False
def _va_pif_2_lif(self, pif):
return pif + '.0'
def _va_set_interface_ip(self, pif, cidr):
LOG.debug("_va_set_interface_ip: %(pif)s %(cidr)s",
{'pif': pif, 'cidr': cidr})
lif = self._va_pif_2_lif(pif)
obj = va_utils.REST_INTF_NAME % pif + va_utils.REST_LOGIC_NAME % lif
body = {
'name': lif,
'family': 'ipv4',
'address': cidr
}
self.rest.rest_api('PUT', va_utils.REST_URL_CONF + obj, body)
def _va_get_port_name(self, port_list, name):
if name:
for p in port_list:
if p['VM name'] == name:
return p['name']
def _va_config_trusted_zone(self, ri, plist):
zone = va_utils.get_trusted_zone_name(ri)
LOG.debug("_va_config_trusted_zone: %s", zone)
body = {
'name': zone,
'type': 'L3',
'interface': []
}
if not self._va_unset_zone_interfaces(zone):
# if zone doesn't exist, create it
self.rest.rest_api('POST', va_utils.REST_URL_CONF_ZONE, body)
self.rest.commit()
# add new internal ports to trusted zone
for p in ri.internal_ports:
if p['admin_state_up']:
dev = self.get_internal_device_name(p['id'])
pif = self._va_get_port_name(plist, dev)
if pif:
lif = self._va_pif_2_lif(pif)
if lif not in body['interface']:
body['interface'].append(lif)
self._va_set_interface_ip(pif, p['ip_cidr'])
if body['interface']:
self.rest.rest_api('PUT', va_utils.REST_URL_CONF_ZONE, body)
self.rest.commit()
def _va_config_untrusted_zone(self, ri, plist):
zone = va_utils.get_untrusted_zone_name(ri)
LOG.debug("_va_config_untrusted_zone: %s", zone)
body = {
'name': zone,
'type': 'L3',
'interface': []
}
if not self._va_unset_zone_interfaces(zone):
# if zone doesn't exist, create it
self.rest.rest_api('POST', va_utils.REST_URL_CONF_ZONE, body)
self.rest.commit()
# add new gateway ports to untrusted zone
if ri.ex_gw_port:
LOG.debug("_va_config_untrusted_zone: gw=%r", ri.ex_gw_port)
dev = self.get_external_device_name(ri.ex_gw_port['id'])
pif = self._va_get_port_name(plist, dev)
if pif:
lif = self._va_pif_2_lif(pif)
self._va_set_interface_ip(pif, ri.ex_gw_port['ip_cidr'])
body['interface'].append(lif)
self.rest.rest_api('PUT', va_utils.REST_URL_CONF_ZONE, body)
self.rest.commit()
def _va_config_router_snat_rules(self, ri, plist):
LOG.debug('_va_config_router_snat_rules: %s', ri.router['id'])
prefix = va_utils.get_snat_rule_name(ri)
self.rest.del_cfg_objs(va_utils.REST_URL_CONF_NAT_RULE, prefix)
if not ri.enable_snat:
return
for idx, p in enumerate(ri.internal_ports):
if p['admin_state_up']:
dev = self.get_internal_device_name(p['id'])
pif = self._va_get_port_name(plist, dev)
if pif:
net = netaddr.IPNetwork(p['ip_cidr'])
body = {
'name': '%s_%d' % (prefix, idx),
'ingress-context-type': 'interface',
'ingress-index': self._va_pif_2_lif(pif),
'source-address': [
[str(netaddr.IPAddress(net.first + 2)),
str(netaddr.IPAddress(net.last - 1))]
],
'flag': 'interface translate-source'
}
self.rest.rest_api('POST',
va_utils.REST_URL_CONF_NAT_RULE,
body)
if ri.internal_ports:
self.rest.commit()
def _va_config_floating_ips(self, ri):
LOG.debug('_va_config_floating_ips: %s', ri.router['id'])
prefix = va_utils.get_dnat_rule_name(ri)
self.rest.del_cfg_objs(va_utils.REST_URL_CONF_NAT_RULE, prefix)
# add new dnat rules
for idx, fip in enumerate(ri.floating_ips):
body = {
'name': '%s_%d' % (prefix, idx),
'ingress-context-type': 'zone',
'ingress-index': va_utils.get_untrusted_zone_name(ri),
'destination-address': [[fip['floating_ip_address'],
fip['floating_ip_address']]],
'static': [fip['fixed_ip_address'], fip['fixed_ip_address']],
'flag': 'translate-destination'
}
self.rest.rest_api('POST', va_utils.REST_URL_CONF_NAT_RULE, body)
if ri.floating_ips:
self.rest.commit()
def process_router(self, ri):
LOG.debug("process_router: %s", ri.router['id'])
super(vArmourL3NATAgent, self).process_router(ri)
self.rest.auth()
# read internal port name and configuration port name map
resp = self.rest.rest_api('GET', va_utils.REST_URL_INTF_MAP)
if resp and resp['status'] == 200:
try:
plist = resp['body']['response']
except ValueError:
LOG.warning(_LW("Unable to parse interface mapping."))
return
else:
LOG.warning(_LW("Unable to read interface mapping."))
return
if ri.ex_gw_port:
self._set_subnet_info(ri.ex_gw_port)
self._va_config_trusted_zone(ri, plist)
self._va_config_untrusted_zone(ri, plist)
self._va_config_router_snat_rules(ri, plist)
self._va_config_floating_ips(ri)
def _handle_router_snat_rules(self, ri, ex_gw_port,
interface_name, action):
return
def _send_gratuitous_arp_packet(self, ri, interface_name, ip_address):
return
def external_gateway_added(self, ri, ex_gw_port,
interface_name, internal_cidrs):
LOG.debug("external_gateway_added: %s", ri.router['id'])
if not ip_lib.device_exists(interface_name, namespace=ri.ns_name):
self.driver.plug(ex_gw_port['network_id'],
ex_gw_port['id'], interface_name,
ex_gw_port['mac_address'],
bridge=self.conf.external_network_bridge,
namespace=ri.ns_name,
prefix=agent.EXTERNAL_DEV_PREFIX)
self.driver.init_l3(interface_name, [ex_gw_port['ip_cidr']],
namespace=ri.ns_name)
def _update_routing_table(self, ri, operation, route):
return
class vArmourL3NATAgentWithStateReport(vArmourL3NATAgent,
agent.L3NATAgentWithStateReport):
pass
def main():
conf = cfg.CONF
conf.register_opts(l3_config.OPTS)
conf.register_opts(ha.OPTS)
config.register_interface_driver_opts_helper(conf)
config.register_agent_state_opts_helper(conf)
conf.register_opts(interface.OPTS)
conf.register_opts(external_process.OPTS)
common_config.init(sys.argv[1:])
config.setup_logging()
server = neutron_service.Service.create(
binary='neutron-l3-agent',
topic=f_const.L3_AGENT,
report_interval=cfg.CONF.AGENT.report_interval,
manager='neutron_fwaas.services.firewall.agents.varmour.'
'varmour_router.vArmourL3NATAgentWithStateReport')
service.launch(conf, server).wait()
neutron-fwaas-8.0.0/neutron_fwaas/services/firewall/agents/varmour/varmour_utils.py 0000775 0005670 0005671 00000004064 12701407720 032224 0 ustar jenkins jenkins 0000000 0000000 # Copyright 2013 vArmour Networks Inc.
# All Rights Reserved.
#
# 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.
ROUTER_OBJ_PREFIX = 'r-'
OBJ_PREFIX_LEN = 8
TRUST_ZONE = '_z_trust'
UNTRUST_ZONE = '_z_untrust'
SNAT_RULE = '_snat'
DNAT_RULE = '_dnat'
ROUTER_POLICY = '_p'
REST_URL_CONF = '/config'
REST_URL_AUTH = '/auth'
REST_URL_COMMIT = '/commit'
REST_URL_INTF_MAP = '/operation/interface/mapping'
REST_URL_CONF_NAT_RULE = REST_URL_CONF + '/nat/rule'
REST_URL_CONF_ZONE = REST_URL_CONF + '/zone'
REST_URL_CONF_POLICY = REST_URL_CONF + '/policy'
REST_URL_CONF_ADDR = REST_URL_CONF + '/address'
REST_URL_CONF_SERVICE = REST_URL_CONF + '/service'
REST_ZONE_NAME = '/zone/"name:%s"'
REST_INTF_NAME = '/interface/"name:%s"'
REST_LOGIC_NAME = '/logical/"name:%s"'
REST_SERVICE_NAME = '/service/"name:%s"/rule'
def get_router_object_prefix(ri):
return ROUTER_OBJ_PREFIX + ri.router['id'][:OBJ_PREFIX_LEN]
def get_firewall_object_prefix(ri, fw):
return get_router_object_prefix(ri) + '-' + fw['id'][:OBJ_PREFIX_LEN]
def get_trusted_zone_name(ri):
return get_router_object_prefix(ri) + TRUST_ZONE
def get_untrusted_zone_name(ri):
return get_router_object_prefix(ri) + UNTRUST_ZONE
def get_snat_rule_name(ri):
return get_router_object_prefix(ri) + SNAT_RULE
def get_dnat_rule_name(ri):
return get_router_object_prefix(ri) + DNAT_RULE
def get_router_policy_name(ri):
return get_router_object_prefix(ri) + ROUTER_POLICY
def get_firewall_policy_name(ri, fw, rule):
return get_firewall_object_prefix(ri, fw) + rule['id'][:OBJ_PREFIX_LEN]
neutron-fwaas-8.0.0/neutron_fwaas/services/firewall/agents/__init__.py 0000664 0005670 0005671 00000000000 12701407720 027334 0 ustar jenkins jenkins 0000000 0000000 neutron-fwaas-8.0.0/neutron_fwaas/services/firewall/agents/vyatta/ 0000775 0005670 0005671 00000000000 12701410073 026540 5 ustar jenkins jenkins 0000000 0000000 neutron-fwaas-8.0.0/neutron_fwaas/services/firewall/agents/vyatta/fwaas_agent.py 0000664 0005670 0005671 00000002772 12701407720 031406 0 ustar jenkins jenkins 0000000 0000000 # Copyright 2015 Brocade Communications System, Inc.
# All Rights Reserved.
#
# 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.
#
from networking_brocade.vyatta.common import l3_agent as vyatta_l3
from neutron.agent import l3_agent
from neutron_fwaas.services.firewall.agents.vyatta import firewall_service
class VyattaFirewallAgent(vyatta_l3.L3AgentMiddleware):
"""Brocade Neutron Firewall agent for Vyatta vRouter.
The base class FWaaSL3AgentRpcCallback of the VyattaFirewallAgent creates
the reference FirewallService object that loads the VyattaFirewallDriver
class.The VyattaFirewallService class registers callbacks and subscribes
to router events.
"""
def __init__(self, host, conf=None):
super(VyattaFirewallAgent, self).__init__(host, conf)
self.service = firewall_service.VyattaFirewallService(self)
def main():
l3_agent.main(
manager='neutron_fwaas.services.firewall.agents.vyatta.'
'fwaas_agent.VyattaFirewallAgent')
neutron-fwaas-8.0.0/neutron_fwaas/services/firewall/agents/vyatta/__init__.py 0000664 0005670 0005671 00000000000 12701407720 030644 0 ustar jenkins jenkins 0000000 0000000 neutron-fwaas-8.0.0/neutron_fwaas/services/firewall/agents/vyatta/firewall_service.py 0000664 0005670 0005671 00000004267 12701407720 032455 0 ustar jenkins jenkins 0000000 0000000 # Copyright 2015 Brocade Communications System, Inc.
# All Rights Reserved.
#
# 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.
#
from neutron.callbacks import events
from neutron.callbacks import registry
from neutron.callbacks import resources
from neutron import context
from oslo_log import log as logging
from neutron_fwaas.services.firewall.agents.vyatta import vyatta_utils
LOG = logging.getLogger(__name__)
class VyattaFirewallService(object):
# TODO(vishwanathj): Code to be revised in Liberty release to use
# the base class firewall_service.FirewallService for registrations
def __init__(self, l3_agent):
self.conf = l3_agent.conf
registry.subscribe(
sync_firewall_zones, resources.ROUTER, events.AFTER_CREATE)
registry.subscribe(
sync_firewall_zones, resources.ROUTER, events.AFTER_DELETE)
registry.subscribe(
sync_firewall_zones, resources.ROUTER, events.AFTER_UPDATE)
def sync_firewall_zones(resource, event, l3_agent, **kwargs):
LOG.debug('VyattaFirewallService:: sync_firewall_zones() called')
ri = kwargs['router']
ctx = context.Context(None, ri.router['tenant_id'])
client = l3_agent._vyatta_clients_pool.get_by_db_lookup(
ri.router['id'], ctx)
fw_list = l3_agent.fwplugin_rpc.get_firewalls_for_tenant(ctx)
if fw_list:
zone_cmds = []
for fw in fw_list:
if ri.router['id'] in fw['router_ids']:
fw_name = vyatta_utils.get_firewall_name(ri, fw)
zone_cmds.extend(vyatta_utils.get_zone_cmds(client, ri,
fw_name))
client.exec_cmd_batch(zone_cmds)
neutron-fwaas-8.0.0/neutron_fwaas/services/firewall/agents/vyatta/vyatta_utils.py 0000775 0005670 0005671 00000006107 12701407720 031656 0 ustar jenkins jenkins 0000000 0000000 # Copyright 2015 Brocade Communications System, Inc.
# All Rights Reserved.
#
# 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.
#
from networking_brocade.vyatta.vrouter import client as vyatta_client
from neutron_lib import constants as l3_constants
from six.moves.urllib import parse
TRUST_ZONE = 'Internal_Trust'
UNTRUST_ZONE = 'External_Untrust'
ZONE_INTERFACE_CMD = 'zone-policy/zone/{0}/interface/{1}'
ZONE_FIREWALL_CMD = 'zone-policy/zone/{0}/from/{1}/firewall/name/{2}'
def get_firewall_name(ri, fw):
"""Make firewall name for Vyatta vRouter
Vyatta vRouter REST API allows firewall name length
up to 28 characters.
"""
return fw['id'].replace('-', '')[:28]
def get_trusted_zone_name(ri):
return TRUST_ZONE
def get_untrusted_zone_name(ri):
return UNTRUST_ZONE
def get_zone_cmds(rest_api, ri, fw_name):
"""Return zone update commands for Vyatta vRouter.
Commands chain drops all zone-policy zones and create new zones
based on internal interfaces and external gateway.
"""
cmd_list = []
# Delete the zone policies
cmd_list.append(vyatta_client.DeleteCmd("zone-policy"))
# Configure trusted zone
trusted_zone_name = None
# Add internal ports to trusted zone
if l3_constants.INTERFACE_KEY in ri.router:
trusted_zone_name = parse.quote_plus(get_trusted_zone_name(ri))
for port in ri.router[l3_constants.INTERFACE_KEY]:
eth_if_id = rest_api.get_ethernet_if_id(port['mac_address'])
cmd_list.append(vyatta_client.SetCmd(
ZONE_INTERFACE_CMD.format(trusted_zone_name, eth_if_id)))
# Configure untrusted zone
untrusted_zone_name = get_untrusted_zone_name(ri)
if untrusted_zone_name is not None:
# Add external ports to untrusted zone
if 'gw_port' in ri.router:
gw_port = ri.router['gw_port']
eth_if_id = rest_api.get_ethernet_if_id(gw_port['mac_address'])
cmd_list.append(vyatta_client.SetCmd(
ZONE_INTERFACE_CMD.format(untrusted_zone_name, eth_if_id)))
if trusted_zone_name is not None:
# Associate firewall to zone
cmd_list.append(vyatta_client.SetCmd(
ZONE_FIREWALL_CMD.format(
trusted_zone_name, untrusted_zone_name,
parse.quote_plus(fw_name))))
cmd_list.append(vyatta_client.SetCmd(
ZONE_FIREWALL_CMD.format(
untrusted_zone_name, trusted_zone_name,
parse.quote_plus(fw_name))))
return cmd_list
neutron-fwaas-8.0.0/neutron_fwaas/services/firewall/agents/firewall_service.py 0000664 0005670 0005671 00000003143 12701407720 031135 0 ustar jenkins jenkins 0000000 0000000 # Copyright 2014 OpenStack Foundation.
# All Rights Reserved.
#
# 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.
from neutron.services import provider_configuration as provconf
from oslo_config import cfg
from oslo_log import log as logging
from oslo_utils import importutils
from neutron_fwaas._i18n import _
LOG = logging.getLogger(__name__)
FIREWALL_DRIVERS = 'firewall_drivers'
class FirewallService(object):
"""Firewall Service observer."""
def load_device_drivers(self):
"""Loads a single device driver for FWaaS."""
device_driver = provconf.get_provider_driver_class(
cfg.CONF.fwaas.driver, FIREWALL_DRIVERS)
try:
driver = importutils.import_object(device_driver)
LOG.debug('Loaded FWaaS device driver: %s', device_driver)
return driver
except ImportError:
msg = _('Error importing FWaaS device driver: %s')
raise ImportError(msg % device_driver)
except ValueError:
msg = _('Configuration error - no FWaaS device_driver specified')
raise ValueError(msg)
neutron-fwaas-8.0.0/neutron_fwaas/services/firewall/fwaas_plugin.py 0000664 0005670 0005671 00000041541 12701407720 027012 0 ustar jenkins jenkins 0000000 0000000 # Copyright 2013 Big Switch Networks, Inc.
# All Rights Reserved.
#
# 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.
from neutron.api.v2 import attributes as attr
from neutron.common import rpc as n_rpc
from neutron import context as neutron_context
from neutron import manager
from neutron.plugins.common import constants as n_const
from oslo_config import cfg
from oslo_log import log as logging
import oslo_messaging
from neutron_fwaas._i18n import _LW
from neutron_fwaas.common import fwaas_constants as f_const
from neutron_fwaas.db.firewall import firewall_db
from neutron_fwaas.db.firewall import firewall_router_insertion_db
from neutron_fwaas.extensions import firewall as fw_ext
LOG = logging.getLogger(__name__)
class FirewallCallbacks(object):
target = oslo_messaging.Target(version='1.0')
def __init__(self, plugin):
super(FirewallCallbacks, self).__init__()
self.plugin = plugin
def set_firewall_status(self, context, firewall_id, status, **kwargs):
"""Agent uses this to set a firewall's status."""
LOG.debug("Setting firewall %s to status: %s" % (firewall_id, status))
# Sanitize status first
if status in (n_const.ACTIVE, n_const.DOWN, n_const.INACTIVE):
to_update = status
else:
to_update = n_const.ERROR
# ignore changing status if firewall expects to be deleted
# That case means that while some pending operation has been
# performed on the backend, neutron server received delete request
# and changed firewall status to PENDING_DELETE
updated = self.plugin.update_firewall_status(
context, firewall_id, to_update, not_in=(n_const.PENDING_DELETE,))
if updated:
LOG.debug("firewall %s status set: %s" % (firewall_id, to_update))
return updated and to_update != n_const.ERROR
def firewall_deleted(self, context, firewall_id, **kwargs):
"""Agent uses this to indicate firewall is deleted."""
LOG.debug("firewall_deleted() called")
with context.session.begin(subtransactions=True):
fw_db = self.plugin._get_firewall(context, firewall_id)
# allow to delete firewalls in ERROR state
if fw_db.status in (n_const.PENDING_DELETE, n_const.ERROR):
self.plugin.delete_db_firewall_object(context, firewall_id)
return True
else:
LOG.warning(_LW('Firewall %(fw)s unexpectedly deleted by '
'agent, status was %(status)s'),
{'fw': firewall_id, 'status': fw_db.status})
fw_db.update({"status": n_const.ERROR})
return False
def get_firewalls_for_tenant(self, context, **kwargs):
"""Agent uses this to get all firewalls and rules for a tenant."""
LOG.debug("get_firewalls_for_tenant() called")
fw_list = []
for fw in self.plugin.get_firewalls(context):
fw_with_rules = self.plugin._make_firewall_dict_with_rules(
context, fw['id'])
if fw['status'] == n_const.PENDING_DELETE:
fw_with_rules['add-router-ids'] = []
fw_with_rules['del-router-ids'] = (
self.plugin.get_firewall_routers(context, fw['id']))
else:
fw_with_rules['add-router-ids'] = (
self.plugin.get_firewall_routers(context, fw['id']))
fw_with_rules['del-router-ids'] = []
fw_list.append(fw_with_rules)
return fw_list
def get_firewalls_for_tenant_without_rules(self, context, **kwargs):
"""Agent uses this to get all firewalls for a tenant."""
LOG.debug("get_firewalls_for_tenant_without_rules() called")
fw_list = [fw for fw in self.plugin.get_firewalls(context)]
return fw_list
def get_tenants_with_firewalls(self, context, **kwargs):
"""Agent uses this to get all tenants that have firewalls."""
LOG.debug("get_tenants_with_firewalls() called")
ctx = neutron_context.get_admin_context()
fw_list = self.plugin.get_firewalls(ctx)
fw_tenant_list = list(set(fw['tenant_id'] for fw in fw_list))
return fw_tenant_list
class FirewallAgentApi(object):
"""Plugin side of plugin to agent RPC API."""
def __init__(self, topic, host):
self.host = host
target = oslo_messaging.Target(topic=topic, version='1.0')
self.client = n_rpc.get_client(target)
def create_firewall(self, context, firewall):
cctxt = self.client.prepare(fanout=True)
cctxt.cast(context, 'create_firewall', firewall=firewall,
host=self.host)
def update_firewall(self, context, firewall):
cctxt = self.client.prepare(fanout=True)
cctxt.cast(context, 'update_firewall', firewall=firewall,
host=self.host)
def delete_firewall(self, context, firewall):
cctxt = self.client.prepare(fanout=True)
cctxt.cast(context, 'delete_firewall', firewall=firewall,
host=self.host)
class FirewallPlugin(
firewall_db.Firewall_db_mixin,
firewall_router_insertion_db.FirewallRouterInsertionDbMixin):
"""Implementation of the Neutron Firewall Service Plugin.
This class manages the workflow of FWaaS request/response.
Most DB related works are implemented in class
firewall_db.Firewall_db_mixin.
"""
supported_extension_aliases = ["fwaas", "fwaasrouterinsertion"]
path_prefix = fw_ext.FIREWALL_PREFIX
def __init__(self):
"""Do the initialization for the firewall service plugin here."""
self.start_rpc_listeners()
self.agent_rpc = FirewallAgentApi(
f_const.L3_AGENT,
cfg.CONF.host
)
firewall_db.subscribe()
def start_rpc_listeners(self):
self.endpoints = [FirewallCallbacks(self)]
self.conn = n_rpc.create_connection()
self.conn.create_consumer(
f_const.FIREWALL_PLUGIN, self.endpoints, fanout=False)
return self.conn.consume_in_threads()
def _rpc_update_firewall(self, context, firewall_id):
status_update = {"firewall": {"status": n_const.PENDING_UPDATE}}
super(FirewallPlugin, self).update_firewall(context, firewall_id,
status_update)
fw_with_rules = self._make_firewall_dict_with_rules(context,
firewall_id)
# this is triggered on an update to fw rule or policy, no
# change in associated routers.
fw_with_rules['add-router-ids'] = self.get_firewall_routers(
context, firewall_id)
fw_with_rules['del-router-ids'] = []
self.agent_rpc.update_firewall(context, fw_with_rules)
def _rpc_update_firewall_policy(self, context, firewall_policy_id):
firewall_policy = self.get_firewall_policy(context, firewall_policy_id)
if firewall_policy:
for firewall_id in firewall_policy['firewall_list']:
self._rpc_update_firewall(context, firewall_id)
def _ensure_update_firewall(self, context, firewall_id):
fwall = self.get_firewall(context, firewall_id)
if fwall['status'] in [n_const.PENDING_CREATE,
n_const.PENDING_UPDATE,
n_const.PENDING_DELETE]:
raise fw_ext.FirewallInPendingState(firewall_id=firewall_id,
pending_state=fwall['status'])
def _ensure_update_firewall_policy(self, context, firewall_policy_id):
firewall_policy = self.get_firewall_policy(context, firewall_policy_id)
if firewall_policy and 'firewall_list' in firewall_policy:
for firewall_id in firewall_policy['firewall_list']:
self._ensure_update_firewall(context, firewall_id)
def _ensure_update_firewall_rule(self, context, firewall_rule_id):
fw_rule = self.get_firewall_rule(context, firewall_rule_id)
if 'firewall_policy_id' in fw_rule and fw_rule['firewall_policy_id']:
self._ensure_update_firewall_policy(context,
fw_rule['firewall_policy_id'])
def _get_routers_for_create_firewall(self, tenant_id, context, firewall):
# pop router_id as this goes in the router association db
# and not firewall db
router_ids = firewall['firewall'].pop('router_ids', None)
if router_ids == attr.ATTR_NOT_SPECIFIED:
# old semantics router-ids keyword not specified pick up
# all routers on tenant.
l3_plugin = manager.NeutronManager.get_service_plugins().get(
n_const.L3_ROUTER_NAT)
ctx = neutron_context.get_admin_context()
routers = l3_plugin.get_routers(ctx)
router_ids = [
router['id']
for router in routers
if router['tenant_id'] == tenant_id]
# validation can still fail this if there is another fw
# which is associated with one of these routers.
self.validate_firewall_routers_not_in_use(context, router_ids)
return router_ids
else:
if not router_ids:
# This indicates that user specifies no routers.
return []
else:
# some router(s) provided.
self.validate_firewall_routers_not_in_use(context, router_ids)
return router_ids
def create_firewall(self, context, firewall):
LOG.debug("create_firewall() called")
fw_new_rtrs = self._get_routers_for_create_firewall(
firewall['firewall']['tenant_id'], context, firewall)
if not fw_new_rtrs:
# no messaging to agent needed, and fw needs to go
# to INACTIVE(no associated rtrs) state.
status = n_const.INACTIVE
fw = super(FirewallPlugin, self).create_firewall(
context, firewall, status)
fw['router_ids'] = []
return fw
else:
fw = super(FirewallPlugin, self).create_firewall(
context, firewall)
fw['router_ids'] = fw_new_rtrs
fw_with_rules = (
self._make_firewall_dict_with_rules(context, fw['id']))
fw_with_rtrs = {'fw_id': fw['id'],
'router_ids': fw_new_rtrs}
self.set_routers_for_firewall(context, fw_with_rtrs)
fw_with_rules['add-router-ids'] = fw_new_rtrs
fw_with_rules['del-router-ids'] = []
self.agent_rpc.create_firewall(context, fw_with_rules)
return fw
def update_firewall(self, context, id, firewall):
LOG.debug("update_firewall() called on firewall %s", id)
self._ensure_update_firewall(context, id)
# pop router_id as this goes in the router association db
# and not firewall db
router_ids = firewall['firewall'].pop('router_ids', None)
fw_current_rtrs = self.get_firewall_routers(context, id)
if router_ids is not None:
if router_ids == []:
# This indicates that user is indicating no routers.
fw_new_rtrs = []
else:
self.validate_firewall_routers_not_in_use(
context, router_ids, id)
fw_new_rtrs = router_ids
self.update_firewall_routers(context, {'fw_id': id,
'router_ids': fw_new_rtrs})
else:
# router-ids keyword not specified for update pick up
# existing routers.
fw_new_rtrs = self.get_firewall_routers(context, id)
if not fw_new_rtrs and not fw_current_rtrs:
# no messaging to agent needed, and we need to continue
# in INACTIVE state
firewall['firewall']['status'] = n_const.INACTIVE
fw = super(FirewallPlugin, self).update_firewall(
context, id, firewall)
fw['router_ids'] = []
return fw
else:
firewall['firewall']['status'] = n_const.PENDING_UPDATE
fw = super(FirewallPlugin, self).update_firewall(
context, id, firewall)
fw['router_ids'] = fw_new_rtrs
fw_with_rules = (
self._make_firewall_dict_with_rules(context, fw['id']))
# determine rtrs to add fw to and del from
fw_with_rules['add-router-ids'] = fw_new_rtrs
fw_with_rules['del-router-ids'] = list(
set(fw_current_rtrs).difference(set(fw_new_rtrs)))
# last-router drives agent to ack with status to set state to INACTIVE
fw_with_rules['last-router'] = not fw_new_rtrs
LOG.debug("update_firewall %s: Add Routers: %s, Del Routers: %s",
fw['id'],
fw_with_rules['add-router-ids'],
fw_with_rules['del-router-ids'])
self.agent_rpc.update_firewall(context, fw_with_rules)
return fw
def delete_db_firewall_object(self, context, id):
super(FirewallPlugin, self).delete_firewall(context, id)
def delete_firewall(self, context, id):
LOG.debug("delete_firewall() called on firewall %s", id)
fw_with_rules = (
self._make_firewall_dict_with_rules(context, id))
fw_with_rules['del-router-ids'] = self.get_firewall_routers(
context, id)
fw_with_rules['add-router-ids'] = []
if not fw_with_rules['del-router-ids']:
# no routers to delete on the agent side
self.delete_db_firewall_object(context, id)
else:
status = {"firewall": {"status": n_const.PENDING_DELETE}}
super(FirewallPlugin, self).update_firewall(context, id, status)
# Reflect state change in fw_with_rules
fw_with_rules['status'] = status['firewall']['status']
self.agent_rpc.delete_firewall(context, fw_with_rules)
def update_firewall_policy(self, context, id, firewall_policy):
LOG.debug("update_firewall_policy() called")
self._ensure_update_firewall_policy(context, id)
fwp = super(FirewallPlugin,
self).update_firewall_policy(context, id, firewall_policy)
self._rpc_update_firewall_policy(context, id)
return fwp
def update_firewall_rule(self, context, id, firewall_rule):
LOG.debug("update_firewall_rule() called")
self._ensure_update_firewall_rule(context, id)
fwr = super(FirewallPlugin,
self).update_firewall_rule(context, id, firewall_rule)
firewall_policy_id = fwr['firewall_policy_id']
if firewall_policy_id:
self._rpc_update_firewall_policy(context, firewall_policy_id)
return fwr
def _notify_firewall_updates(self, context, resource, update_info):
notifier = n_rpc.get_notifier('network')
notifier.info(context, resource, update_info)
def insert_rule(self, context, id, rule_info):
LOG.debug("insert_rule() called")
self._ensure_update_firewall_policy(context, id)
fwp = super(FirewallPlugin,
self).insert_rule(context, id, rule_info)
self._rpc_update_firewall_policy(context, id)
resource = 'firewall_policy.update.insert_rule'
self._notify_firewall_updates(context, resource, rule_info)
return fwp
def remove_rule(self, context, id, rule_info):
LOG.debug("remove_rule() called")
self._ensure_update_firewall_policy(context, id)
fwp = super(FirewallPlugin,
self).remove_rule(context, id, rule_info)
self._rpc_update_firewall_policy(context, id)
resource = 'firewall_policy.update.remove_rule'
self._notify_firewall_updates(context, resource, rule_info)
return fwp
def get_firewalls(self, context, filters=None, fields=None):
LOG.debug("fwaas get_firewalls() called")
fw_list = super(FirewallPlugin, self).get_firewalls(
context, filters, fields)
for fw in fw_list:
fw_current_rtrs = self.get_firewall_routers(context, fw['id'])
fw['router_ids'] = fw_current_rtrs
return fw_list
def get_firewall(self, context, id, fields=None):
LOG.debug("fwaas get_firewall() called")
res = super(FirewallPlugin, self).get_firewall(
context, id, fields)
fw_current_rtrs = self.get_firewall_routers(context, id)
res['router_ids'] = fw_current_rtrs
return res
neutron-fwaas-8.0.0/neutron_fwaas/services/__init__.py 0000664 0005670 0005671 00000000000 12701407720 024246 0 ustar jenkins jenkins 0000000 0000000 neutron-fwaas-8.0.0/neutron_fwaas/_i18n.py 0000664 0005670 0005671 00000002521 12701407720 021614 0 ustar jenkins jenkins 0000000 0000000 # All Rights Reserved.
#
# 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.
import oslo_i18n
DOMAIN = "neutron_fwaas"
_translators = oslo_i18n.TranslatorFactory(domain=DOMAIN)
# The primary translation function using the well-known name "_"
_ = _translators.primary
# The contextual translation function using the name "_C"
_C = _translators.contextual_form
# The plural translation function using the name "_P"
_P = _translators.plural_form
# Translators for log levels.
#
# The abbreviated names are meant to reflect the usual use of a short
# name like '_'. The "L" is for "log" and the other letter comes from
# the level.
_LI = _translators.log_info
_LW = _translators.log_warning
_LE = _translators.log_error
_LC = _translators.log_critical
def get_available_languages():
return oslo_i18n.get_available_languages(DOMAIN)
neutron-fwaas-8.0.0/neutron_fwaas/extensions/ 0000775 0005670 0005671 00000000000 12701410073 022516 5 ustar jenkins jenkins 0000000 0000000 neutron-fwaas-8.0.0/neutron_fwaas/extensions/cisco/ 0000775 0005670 0005671 00000000000 12701410073 023616 5 ustar jenkins jenkins 0000000 0000000 neutron-fwaas-8.0.0/neutron_fwaas/extensions/cisco/__init__.py 0000664 0005670 0005671 00000000000 12701407720 025722 0 ustar jenkins jenkins 0000000 0000000 neutron-fwaas-8.0.0/neutron_fwaas/extensions/cisco/csr_firewall_insertion.py 0000664 0005670 0005671 00000004764 12701407721 030757 0 ustar jenkins jenkins 0000000 0000000 # Copyright 2015 Cisco Systems, Inc. All rights reserved.
#
# 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.
from neutron.api import extensions
from neutron.api.v2 import attributes as attr
from neutron.common import exceptions as excp
from neutron_fwaas._i18n import _
class InvalidInterfaceForCSRFW(excp.NotFound):
message = _("Interface id %(port_id)s provided "
"not valid for Cisco CSR Firewall")
class InvalidRouterAssociationForCSRFW(excp.InvalidInput):
message = _("Port id %(port_id)s provided "
"for Cisco CSR Firewall associated with different Router")
class InvalidRouterHostingInfoForCSRFW(excp.NotFound):
message = _("Interface id %(port_id)s provided "
"does not have Hosting Info for Cisco CSR Firewall")
csr_firewall_direction = ['inside', 'outside', 'both']
EXTENDED_ATTRIBUTES_2_0 = {
'firewalls': {
'port_id': {'allow_post': True, 'allow_put': True,
'validate': {'type:uuid': None},
'is_visible': True, 'default': attr.ATTR_NOT_SPECIFIED},
'direction': {'allow_post': True, 'allow_put': True,
'validate': {'type:values': csr_firewall_direction},
'is_visible': True, 'default': attr.ATTR_NOT_SPECIFIED},
}
}
class Csr_firewall_insertion(extensions.ExtensionDescriptor):
@classmethod
def get_name(cls):
return "CSR Firewall insertion"
@classmethod
def get_alias(cls):
return "csrfirewallinsertion"
@classmethod
def get_description(cls):
return "Firewall insertion for Cisco CSR"
@classmethod
def get_namespace(cls):
return ("http://docs.openstack.org/ext/neutron/"
"csrfirewallinsertion/api/v1.0")
@classmethod
def get_updated(cls):
return "2014-08-13T10:00:00-00:00"
def get_extended_resources(self, version):
if version == "2.0":
return EXTENDED_ATTRIBUTES_2_0
else:
return {}
neutron-fwaas-8.0.0/neutron_fwaas/extensions/__init__.py 0000664 0005670 0005671 00000000000 12701407720 024622 0 ustar jenkins jenkins 0000000 0000000 neutron-fwaas-8.0.0/neutron_fwaas/extensions/firewallrouterinsertion.py 0000664 0005670 0005671 00000006072 12701407721 030104 0 ustar jenkins jenkins 0000000 0000000 # Copyright 2015 Cisco Systems Inc.
# All rights reserved.
#
# 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.
from neutron.api import extensions
from neutron.api.v2 import attributes as attr
from neutron.common import exceptions as nexception
from neutron_fwaas._i18n import _
class FirewallRouterInUse(nexception.InUse):
message = _("Router(s) %(router_ids)s provided already associated with "
"other Firewall(s). ")
EXTENDED_ATTRIBUTES_2_0 = {
'firewalls': {
'router_ids': {'allow_post': True, 'allow_put': True,
'validate': {'type:uuid_list': None},
'is_visible': True, 'default': attr.ATTR_NOT_SPECIFIED},
}
}
class Firewallrouterinsertion(extensions.ExtensionDescriptor):
"""Extension class supporting Firewall and Router(s) association.
The extension enables providing an option to specify router-ids of
routers where the firewall is to be installed. This is supported in
a manner so that the older version of the API continues to be supported.
On a CREATE, if the router_ids option is not specified then the firewall
is installed on all routers on the tenant. If the router-ids option is
provided with a list of routers then the firewall is installed on the
specified routers. If the router-ids option is provided with an empty
list then the firewall is created but put in an INACTIVE state to reflect
that no routers are associated. This firewall can be updated with a list
of routers which will then drive the state to ACTIVE after the agent
installs and acks back. UPDATE also supports the option in a similar
manner. If the router_ids option is not provided, then there is no change
to the existing association with the routers. When the router_is option is
provided with a list of routers or an empty list - this drives the new
set of routers that the firewall is associated with.
"""
@classmethod
def get_name(cls):
return "Firewall Router insertion"
@classmethod
def get_alias(cls):
return "fwaasrouterinsertion"
@classmethod
def get_description(cls):
return "Firewall Router insertion on specified set of routers"
@classmethod
def get_namespace(cls):
return ("http://docs.openstack.org/ext/neutron/fwaasrouterinsertion"
"/api/v1.0")
@classmethod
def get_updated(cls):
return "2015-01-27T10:00:00-00:00"
def get_extended_resources(self, version):
if version == "2.0":
return EXTENDED_ATTRIBUTES_2_0
else:
return {}
neutron-fwaas-8.0.0/neutron_fwaas/extensions/firewall.py 0000664 0005670 0005671 00000043614 12701407721 024713 0 ustar jenkins jenkins 0000000 0000000 # Copyright 2013 Big Switch Networks, Inc.
# All Rights Reserved.
#
# 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.
import abc
from neutron.api import extensions
from neutron.api.v2 import attributes as attr
from neutron.api.v2 import resource_helper
from neutron.common import exceptions as nexception
from neutron.plugins.common import constants as p_const
from neutron.services import service_base
from neutron_lib import constants
from oslo_config import cfg
from oslo_log import log as logging
import six
from neutron_fwaas._i18n import _
LOG = logging.getLogger(__name__)
# Firewall rule action
FWAAS_ALLOW = "allow"
FWAAS_DENY = "deny"
FWAAS_REJECT = "reject"
# Firewall resource path prefix
FIREWALL_PREFIX = "/fw"
# Firewall Exceptions
class FirewallNotFound(nexception.NotFound):
message = _("Firewall %(firewall_id)s could not be found.")
class FirewallInUse(nexception.InUse):
message = _("Firewall %(firewall_id)s is still active.")
class FirewallInPendingState(nexception.Conflict):
message = _("Operation cannot be performed since associated Firewall "
"%(firewall_id)s is in %(pending_state)s.")
class FirewallPolicyNotFound(nexception.NotFound):
message = _("Firewall Policy %(firewall_policy_id)s could not be found.")
class FirewallPolicyInUse(nexception.InUse):
message = _("Firewall Policy %(firewall_policy_id)s is being used.")
class FirewallPolicyConflict(nexception.Conflict):
"""FWaaS exception for firewall policy
Occurs when admin policy tries to use another tenant's unshared
policy.
"""
message = _("Operation cannot be performed since Firewall Policy "
"%(firewall_policy_id)s is not shared and does not belong to "
"your tenant.")
class FirewallRuleSharingConflict(nexception.Conflict):
"""FWaaS exception for firewall rules
When a shared policy is created or updated with unshared rules,
this exception will be raised.
"""
message = _("Operation cannot be performed since Firewall Policy "
"%(firewall_policy_id)s is shared but Firewall Rule "
"%(firewall_rule_id)s is not shared")
class FirewallPolicySharingConflict(nexception.Conflict):
"""FWaaS exception for firewall policy
When a policy is shared without sharing its associated rules,
this exception will be raised.
"""
message = _("Operation cannot be performed. Before sharing Firewall "
"Policy %(firewall_policy_id)s, share associated Firewall "
"Rule %(firewall_rule_id)s")
class FirewallRuleNotFound(nexception.NotFound):
message = _("Firewall Rule %(firewall_rule_id)s could not be found.")
class FirewallRuleInUse(nexception.InUse):
message = _("Firewall Rule %(firewall_rule_id)s is being used.")
class FirewallRuleNotAssociatedWithPolicy(nexception.InvalidInput):
message = _("Firewall Rule %(firewall_rule_id)s is not associated "
" with Firewall Policy %(firewall_policy_id)s.")
class FirewallRuleInvalidProtocol(nexception.InvalidInput):
message = _("Firewall Rule protocol %(protocol)s is not supported. "
"Only protocol values %(values)s and their integer "
"representation (0 to 255) are supported.")
class FirewallRuleInvalidAction(nexception.InvalidInput):
message = _("Firewall rule action %(action)s is not supported. "
"Only action values %(values)s are supported.")
class FirewallRuleInvalidICMPParameter(nexception.InvalidInput):
message = _("%(param)s are not allowed when protocol "
"is set to ICMP.")
class FirewallRuleWithPortWithoutProtocolInvalid(nexception.InvalidInput):
message = _("Source/destination port requires a protocol")
class FirewallRuleInvalidPortValue(nexception.InvalidInput):
message = _("Invalid value for port %(port)s.")
class FirewallRuleInfoMissing(nexception.InvalidInput):
message = _("Missing rule info argument for insert/remove "
"rule operation.")
class FirewallIpAddressConflict(nexception.InvalidInput):
message = _("Invalid input - IP addresses do not agree with IP Version")
# TODO(dougwig) - once this exception is out of neutron, restore this
#class FirewallInternalDriverError(nexception.NeutronException):
# """Fwaas exception for all driver errors.
#
# On any failure or exception in the driver, driver should log it and
# raise this exception to the agent
# """
# message = _("%(driver)s: Internal driver error.")
FirewallInternalDriverError = nexception.FirewallInternalDriverError
class FirewallRuleConflict(nexception.Conflict):
"""Firewall rule conflict exception.
Occurs when admin policy tries to use another tenant's unshared
rule.
"""
message = _("Operation cannot be performed since Firewall Rule "
"%(firewall_rule_id)s is not shared and belongs to "
"another tenant %(tenant_id)s")
fw_valid_protocol_values = [None, constants.PROTO_NAME_TCP,
constants.PROTO_NAME_UDP,
constants.PROTO_NAME_ICMP]
fw_valid_action_values = [FWAAS_ALLOW, FWAAS_DENY, FWAAS_REJECT]
def convert_protocol(value):
if value is None:
return
if value.isdigit():
val = int(value)
if 0 <= val <= 255:
return val
else:
raise FirewallRuleInvalidProtocol(
protocol=value,
values=fw_valid_protocol_values)
elif value.lower() in fw_valid_protocol_values:
return value.lower()
else:
raise FirewallRuleInvalidProtocol(
protocol=value,
values=fw_valid_protocol_values)
def convert_action_to_case_insensitive(value):
if value is None:
return
else:
return value.lower()
def convert_port_to_string(value):
if value is None:
return
else:
return str(value)
def _validate_port_range(data, key_specs=None):
if data is None:
return
data = str(data)
ports = data.split(':')
for p in ports:
try:
val = int(p)
except (ValueError, TypeError):
msg = _("Port '%s' is not a valid number") % p
LOG.debug(msg)
return msg
if val <= 0 or val > 65535:
msg = _("Invalid port '%s'") % p
LOG.debug(msg)
return msg
def _validate_ip_or_subnet_or_none(data, valid_values=None):
if data is None:
return None
msg_ip = attr._validate_ip_address(data, valid_values)
if not msg_ip:
return
msg_subnet = attr._validate_subnet(data, valid_values)
if not msg_subnet:
return
return _("%(msg_ip)s and %(msg_subnet)s") % {'msg_ip': msg_ip,
'msg_subnet': msg_subnet}
attr.validators['type:port_range'] = _validate_port_range
attr.validators['type:ip_or_subnet_or_none'] = _validate_ip_or_subnet_or_none
RESOURCE_ATTRIBUTE_MAP = {
'firewall_rules': {
'id': {'allow_post': False, 'allow_put': False,
'validate': {'type:uuid': None},
'is_visible': True, 'primary_key': True},
'tenant_id': {'allow_post': True, 'allow_put': False,
'required_by_policy': True,
'is_visible': True},
'name': {'allow_post': True, 'allow_put': True,
'validate': {'type:string': attr.NAME_MAX_LEN},
'is_visible': True, 'default': ''},
'description': {'allow_post': True, 'allow_put': True,
'validate': {'type:string':
attr.DESCRIPTION_MAX_LEN},
'is_visible': True, 'default': ''},
'firewall_policy_id': {'allow_post': False, 'allow_put': False,
'validate': {'type:uuid_or_none': None},
'is_visible': True},
'shared': {'allow_post': True, 'allow_put': True,
'default': False, 'convert_to': attr.convert_to_boolean,
'is_visible': True, 'required_by_policy': True,
'enforce_policy': True},
'protocol': {'allow_post': True, 'allow_put': True,
'is_visible': True, 'default': None,
'convert_to': convert_protocol,
'validate': {'type:values': fw_valid_protocol_values}},
'ip_version': {'allow_post': True, 'allow_put': True,
'default': 4, 'convert_to': attr.convert_to_int,
'validate': {'type:values': [4, 6]},
'is_visible': True},
'source_ip_address': {'allow_post': True, 'allow_put': True,
'validate': {'type:ip_or_subnet_or_none': None},
'is_visible': True, 'default': None},
'destination_ip_address': {'allow_post': True, 'allow_put': True,
'validate': {'type:ip_or_subnet_or_none':
None},
'is_visible': True, 'default': None},
'source_port': {'allow_post': True, 'allow_put': True,
'validate': {'type:port_range': None},
'convert_to': convert_port_to_string,
'default': None, 'is_visible': True},
'destination_port': {'allow_post': True, 'allow_put': True,
'validate': {'type:port_range': None},
'convert_to': convert_port_to_string,
'default': None, 'is_visible': True},
'position': {'allow_post': False, 'allow_put': False,
'default': None, 'is_visible': True},
'action': {'allow_post': True, 'allow_put': True,
'convert_to': convert_action_to_case_insensitive,
'validate': {'type:values': fw_valid_action_values},
'is_visible': True, 'default': 'deny'},
'enabled': {'allow_post': True, 'allow_put': True,
'default': True, 'convert_to': attr.convert_to_boolean,
'is_visible': True},
},
'firewall_policies': {
'id': {'allow_post': False, 'allow_put': False,
'validate': {'type:uuid': None},
'is_visible': True,
'primary_key': True},
'tenant_id': {'allow_post': True, 'allow_put': False,
'required_by_policy': True,
'is_visible': True},
'name': {'allow_post': True, 'allow_put': True,
'validate': {'type:string': attr.NAME_MAX_LEN},
'is_visible': True, 'default': ''},
'description': {'allow_post': True, 'allow_put': True,
'validate': {'type:string':
attr.DESCRIPTION_MAX_LEN},
'is_visible': True, 'default': ''},
'shared': {'allow_post': True, 'allow_put': True,
'default': False, 'convert_to': attr.convert_to_boolean,
'is_visible': True, 'required_by_policy': True,
'enforce_policy': True},
'firewall_rules': {'allow_post': True, 'allow_put': True,
'validate': {'type:uuid_list': None},
'convert_to': attr.convert_none_to_empty_list,
'default': None, 'is_visible': True},
'audited': {'allow_post': True, 'allow_put': True,
'default': False, 'convert_to': attr.convert_to_boolean,
'is_visible': True},
},
'firewalls': {
'id': {'allow_post': False, 'allow_put': False,
'validate': {'type:uuid': None},
'is_visible': True,
'primary_key': True},
'tenant_id': {'allow_post': True, 'allow_put': False,
'required_by_policy': True,
'is_visible': True},
'name': {'allow_post': True, 'allow_put': True,
'validate': {'type:string': attr.NAME_MAX_LEN},
'is_visible': True, 'default': ''},
'description': {'allow_post': True, 'allow_put': True,
'validate': {'type:string':
attr.DESCRIPTION_MAX_LEN},
'is_visible': True, 'default': ''},
'admin_state_up': {'allow_post': True, 'allow_put': True,
'default': True,
'convert_to': attr.convert_to_boolean,
'is_visible': True},
'status': {'allow_post': False, 'allow_put': False,
'is_visible': True},
'shared': {'allow_post': True, 'allow_put': True,
'default': False, 'convert_to': attr.convert_to_boolean,
'is_visible': False, 'required_by_policy': True,
'enforce_policy': True},
'firewall_policy_id': {'allow_post': True, 'allow_put': True,
'validate': {'type:uuid_or_none': None},
'is_visible': True},
},
}
# A tenant may have a unique firewall and policy for each router
# when router insertion is used.
# Set default quotas to align with default l3 quota_router of 10
# though keep as separately controllable.
firewall_quota_opts = [
cfg.IntOpt('quota_firewall',
default=10,
help=_('Number of firewalls allowed per tenant. '
'A negative value means unlimited.')),
cfg.IntOpt('quota_firewall_policy',
default=10,
help=_('Number of firewall policies allowed per tenant. '
'A negative value means unlimited.')),
cfg.IntOpt('quota_firewall_rule',
default=100,
help=_('Number of firewall rules allowed per tenant. '
'A negative value means unlimited.')),
]
cfg.CONF.register_opts(firewall_quota_opts, 'QUOTAS')
class Firewall(extensions.ExtensionDescriptor):
@classmethod
def get_name(cls):
return "Firewall service"
@classmethod
def get_alias(cls):
return "fwaas"
@classmethod
def get_description(cls):
return "Extension for Firewall service"
@classmethod
def get_namespace(cls):
return "http://wiki.openstack.org/Neutron/FWaaS/API_1.0"
@classmethod
def get_updated(cls):
return "2013-02-25T10:00:00-00:00"
@classmethod
def get_resources(cls):
special_mappings = {'firewall_policies': 'firewall_policy'}
plural_mappings = resource_helper.build_plural_mappings(
special_mappings, RESOURCE_ATTRIBUTE_MAP)
attr.PLURALS.update(plural_mappings)
action_map = {'firewall_policy': {'insert_rule': 'PUT',
'remove_rule': 'PUT'}}
return resource_helper.build_resource_info(plural_mappings,
RESOURCE_ATTRIBUTE_MAP,
p_const.FIREWALL,
action_map=action_map,
register_quota=True)
@classmethod
def get_plugin_interface(cls):
return FirewallPluginBase
def update_attributes_map(self, attributes):
super(Firewall, self).update_attributes_map(
attributes, extension_attrs_map=RESOURCE_ATTRIBUTE_MAP)
def get_extended_resources(self, version):
if version == "2.0":
return RESOURCE_ATTRIBUTE_MAP
else:
return {}
@six.add_metaclass(abc.ABCMeta)
class FirewallPluginBase(service_base.ServicePluginBase):
def get_plugin_name(self):
return p_const.FIREWALL
def get_plugin_type(self):
return p_const.FIREWALL
def get_plugin_description(self):
return 'Firewall service plugin'
@abc.abstractmethod
def get_firewalls(self, context, filters=None, fields=None):
pass
@abc.abstractmethod
def get_firewall(self, context, id, fields=None):
pass
@abc.abstractmethod
def create_firewall(self, context, firewall):
pass
@abc.abstractmethod
def update_firewall(self, context, id, firewall):
pass
@abc.abstractmethod
def delete_firewall(self, context, id):
pass
@abc.abstractmethod
def get_firewall_rules(self, context, filters=None, fields=None):
pass
@abc.abstractmethod
def get_firewall_rule(self, context, id, fields=None):
pass
@abc.abstractmethod
def create_firewall_rule(self, context, firewall_rule):
pass
@abc.abstractmethod
def update_firewall_rule(self, context, id, firewall_rule):
pass
@abc.abstractmethod
def delete_firewall_rule(self, context, id):
pass
@abc.abstractmethod
def get_firewall_policy(self, context, id, fields=None):
pass
@abc.abstractmethod
def get_firewall_policies(self, context, filters=None, fields=None):
pass
@abc.abstractmethod
def create_firewall_policy(self, context, firewall_policy):
pass
@abc.abstractmethod
def update_firewall_policy(self, context, id, firewall_policy):
pass
@abc.abstractmethod
def delete_firewall_policy(self, context, id):
pass
@abc.abstractmethod
def insert_rule(self, context, id, rule_info):
pass
@abc.abstractmethod
def remove_rule(self, context, id, rule_info):
pass
neutron-fwaas-8.0.0/neutron_fwaas/common/ 0000775 0005670 0005671 00000000000 12701410073 021607 5 ustar jenkins jenkins 0000000 0000000 neutron-fwaas-8.0.0/neutron_fwaas/common/__init__.py 0000664 0005670 0005671 00000000000 12701407720 023713 0 ustar jenkins jenkins 0000000 0000000 neutron-fwaas-8.0.0/neutron_fwaas/common/fwaas_constants.py 0000664 0005670 0005671 00000001317 12701407720 025365 0 ustar jenkins jenkins 0000000 0000000 # Copyright 2015 Cisco Systems, Inc
# All Rights Reserved.
#
# 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.
# Constants for "topics"
FIREWALL_PLUGIN = 'q-firewall-plugin'
L3_AGENT = 'l3_agent'
neutron-fwaas-8.0.0/neutron_fwaas/version.py 0000664 0005670 0005671 00000001264 12701407720 022366 0 ustar jenkins jenkins 0000000 0000000 # Copyright 2011 OpenStack Foundation
#
# 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.
import pbr.version
version_info = pbr.version.VersionInfo('neutron-fwaas')
neutron-fwaas-8.0.0/neutron_fwaas/db/ 0000775 0005670 0005671 00000000000 12701410073 020704 5 ustar jenkins jenkins 0000000 0000000 neutron-fwaas-8.0.0/neutron_fwaas/db/firewall/ 0000775 0005670 0005671 00000000000 12701410073 022511 5 ustar jenkins jenkins 0000000 0000000 neutron-fwaas-8.0.0/neutron_fwaas/db/firewall/__init__.py 0000664 0005670 0005671 00000000000 12701407720 024615 0 ustar jenkins jenkins 0000000 0000000 neutron-fwaas-8.0.0/neutron_fwaas/db/firewall/firewall_router_insertion_db.py 0000664 0005670 0005671 00000007511 12701407720 031040 0 ustar jenkins jenkins 0000000 0000000 # Copyright 2015 Cisco Systems Inc.
# All Rights Reserved.
#
# 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.
from neutron.db import model_base
from oslo_log import helpers as log_helpers
from oslo_log import log as logging
import sqlalchemy as sa
from neutron_fwaas.extensions import firewallrouterinsertion as fwrtrins
LOG = logging.getLogger(__name__)
class FirewallRouterAssociation(model_base.BASEV2):
"""Tracks FW Router Association"""
__tablename__ = 'firewall_router_associations'
fw_id = sa.Column(sa.String(36),
sa.ForeignKey('firewalls.id', ondelete="CASCADE"),
primary_key=True)
router_id = sa.Column(sa.String(36),
sa.ForeignKey('routers.id', ondelete="CASCADE"),
primary_key=True)
class FirewallRouterInsertionDbMixin(object):
"""Access methods for the firewall_router_associations table."""
@log_helpers.log_method_call
def set_routers_for_firewall(self, context, fw):
"""Sets the routers associated with the fw."""
with context.session.begin(subtransactions=True):
for r_id in fw['router_ids']:
fw_rtr_db = FirewallRouterAssociation(fw_id=fw['fw_id'],
router_id=r_id)
context.session.add(fw_rtr_db)
@log_helpers.log_method_call
def get_firewall_routers(self, context, fwid):
"""Gets all routers associated with a firewall."""
with context.session.begin(subtransactions=True):
fw_rtr_qry = context.session.query(
FirewallRouterAssociation.router_id)
fw_rtr_rows = fw_rtr_qry.filter_by(fw_id=fwid)
fw_rtrs = [entry.router_id for entry in fw_rtr_rows]
LOG.debug("get_firewall_routers(): fw_rtrs: %s", fw_rtrs)
return fw_rtrs
@log_helpers.log_method_call
def validate_firewall_routers_not_in_use(
self, context, router_ids, fwid=None):
"""Validate if router-ids not associated with any firewall.
If any of the router-ids in the list is already associated with
a firewall, raise an exception else just return.
"""
fw_rtr_qry = context.session.query(FirewallRouterAssociation.router_id)
fw_rtrs = fw_rtr_qry.filter(
FirewallRouterAssociation.router_id.in_(router_ids),
FirewallRouterAssociation.fw_id != fwid).all()
if fw_rtrs:
router_ids = [entry.router_id for entry in fw_rtrs]
raise fwrtrins.FirewallRouterInUse(router_ids=router_ids)
@log_helpers.log_method_call
def update_firewall_routers(self, context, fw):
"""Update the firewall with new routers.
This involves removing existing router associations and replacing
it with the new router associations provided in the update method.
"""
with context.session.begin(subtransactions=True):
fw_rtr_qry = context.session.query(FirewallRouterAssociation)
fw_rtr_qry.filter_by(fw_id=fw['fw_id']).delete()
if fw['router_ids']:
self.set_routers_for_firewall(context, fw)
# TODO(sridar): Investigate potential corner case if rpc failure
# happens on PENDING_UPDATE and agent did not restart. Evaluate
# complexity vs benefit of holding on to old entries until ack
# from agent.
return fw
neutron-fwaas-8.0.0/neutron_fwaas/db/firewall/firewall_db.py 0000664 0005670 0005671 00000072300 12701407720 025344 0 ustar jenkins jenkins 0000000 0000000 # Copyright 2013 Big Switch Networks, Inc.
# All Rights Reserved.
#
# 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.
from neutron.callbacks import events
from neutron.callbacks import registry
from neutron.callbacks import resources
from neutron.db import common_db_mixin as base_db
from neutron.db import model_base
from neutron.db import models_v2
from neutron.extensions import l3
from neutron import manager
from neutron.plugins.common import constants as p_const
from neutron_lib import constants
from oslo_config import cfg
from oslo_log import log as logging
from oslo_utils import uuidutils
import sqlalchemy as sa
from sqlalchemy.ext.orderinglist import ordering_list
from sqlalchemy import orm
from sqlalchemy.orm import exc
import netaddr
from neutron_fwaas.extensions import firewall as fw_ext
LOG = logging.getLogger(__name__)
class FirewallRule(model_base.BASEV2, models_v2.HasId, models_v2.HasTenant):
"""Represents a Firewall rule."""
__tablename__ = 'firewall_rules'
__table_args__ = ({'mysql_collate': 'utf8_bin'})
name = sa.Column(sa.String(255))
description = sa.Column(sa.String(1024))
firewall_policy_id = sa.Column(sa.String(36),
sa.ForeignKey('firewall_policies.id'),
nullable=True)
shared = sa.Column(sa.Boolean)
protocol = sa.Column(sa.String(40))
ip_version = sa.Column(sa.Integer, nullable=False)
source_ip_address = sa.Column(sa.String(46))
destination_ip_address = sa.Column(sa.String(46))
source_port_range_min = sa.Column(sa.Integer)
source_port_range_max = sa.Column(sa.Integer)
destination_port_range_min = sa.Column(sa.Integer)
destination_port_range_max = sa.Column(sa.Integer)
action = sa.Column(sa.Enum('allow', 'deny', 'reject',
name='firewallrules_action'))
enabled = sa.Column(sa.Boolean)
position = sa.Column(sa.Integer)
class Firewall(model_base.BASEV2, models_v2.HasId, models_v2.HasTenant):
"""Represents a Firewall resource."""
__tablename__ = 'firewalls'
__table_args__ = ({'mysql_collate': 'utf8_bin'})
name = sa.Column(sa.String(255))
description = sa.Column(sa.String(1024))
shared = sa.Column(sa.Boolean)
admin_state_up = sa.Column(sa.Boolean)
status = sa.Column(sa.String(16))
firewall_policy_id = sa.Column(sa.String(36),
sa.ForeignKey('firewall_policies.id'),
nullable=True)
class FirewallPolicy(model_base.BASEV2, models_v2.HasId, models_v2.HasTenant):
"""Represents a Firewall Policy resource."""
__tablename__ = 'firewall_policies'
__table_args__ = ({'mysql_collate': 'utf8_bin'})
name = sa.Column(sa.String(255))
description = sa.Column(sa.String(1024))
shared = sa.Column(sa.Boolean)
firewall_rules = orm.relationship(
FirewallRule,
backref=orm.backref('firewall_policies', cascade='all, delete'),
order_by='FirewallRule.position',
collection_class=ordering_list('position', count_from=1))
audited = sa.Column(sa.Boolean)
firewalls = orm.relationship(Firewall, backref='firewall_policies')
class Firewall_db_mixin(fw_ext.FirewallPluginBase, base_db.CommonDbMixin):
"""Mixin class for Firewall DB implementation."""
@property
def _core_plugin(self):
return manager.NeutronManager.get_plugin()
def _get_firewall(self, context, id):
try:
return self._get_by_id(context, Firewall, id)
except exc.NoResultFound:
raise fw_ext.FirewallNotFound(firewall_id=id)
def _get_firewall_policy(self, context, id):
try:
return self._get_by_id(context, FirewallPolicy, id)
except exc.NoResultFound:
raise fw_ext.FirewallPolicyNotFound(firewall_policy_id=id)
def _get_firewall_rule(self, context, id):
try:
return self._get_by_id(context, FirewallRule, id)
except exc.NoResultFound:
raise fw_ext.FirewallRuleNotFound(firewall_rule_id=id)
def _make_firewall_dict(self, fw, fields=None):
res = {'id': fw['id'],
'tenant_id': fw['tenant_id'],
'name': fw['name'],
'description': fw['description'],
'shared': fw['shared'],
'admin_state_up': fw['admin_state_up'],
'status': fw['status'],
'firewall_policy_id': fw['firewall_policy_id']}
return self._fields(res, fields)
def _make_firewall_policy_dict(self, firewall_policy, fields=None):
fw_rules = [rule['id'] for rule in firewall_policy['firewall_rules']]
firewalls = [fw['id'] for fw in firewall_policy['firewalls']]
res = {'id': firewall_policy['id'],
'tenant_id': firewall_policy['tenant_id'],
'name': firewall_policy['name'],
'description': firewall_policy['description'],
'shared': firewall_policy['shared'],
'audited': firewall_policy['audited'],
'firewall_rules': fw_rules,
'firewall_list': firewalls}
return self._fields(res, fields)
def _make_firewall_rule_dict(self, firewall_rule, fields=None):
position = None
# We return the position only if the firewall_rule is bound to a
# firewall_policy.
if firewall_rule['firewall_policy_id']:
position = firewall_rule['position']
src_port_range = self._get_port_range_from_min_max_ports(
firewall_rule['source_port_range_min'],
firewall_rule['source_port_range_max'])
dst_port_range = self._get_port_range_from_min_max_ports(
firewall_rule['destination_port_range_min'],
firewall_rule['destination_port_range_max'])
res = {'id': firewall_rule['id'],
'tenant_id': firewall_rule['tenant_id'],
'name': firewall_rule['name'],
'description': firewall_rule['description'],
'firewall_policy_id': firewall_rule['firewall_policy_id'],
'shared': firewall_rule['shared'],
'protocol': firewall_rule['protocol'],
'ip_version': firewall_rule['ip_version'],
'source_ip_address': firewall_rule['source_ip_address'],
'destination_ip_address':
firewall_rule['destination_ip_address'],
'source_port': src_port_range,
'destination_port': dst_port_range,
'action': firewall_rule['action'],
'position': position,
'enabled': firewall_rule['enabled']}
return self._fields(res, fields)
def _make_firewall_dict_with_rules(self, context, firewall_id):
firewall = self.get_firewall(context, firewall_id)
fw_policy_id = firewall['firewall_policy_id']
if fw_policy_id:
fw_policy = self.get_firewall_policy(context, fw_policy_id)
fw_rules_list = [self.get_firewall_rule(
context, rule_id) for rule_id in fw_policy['firewall_rules']]
firewall['firewall_rule_list'] = fw_rules_list
else:
firewall['firewall_rule_list'] = []
# FIXME(Sumit): If the size of the firewall object we are creating
# here exceeds the largest message size supported by rabbit/qpid
# then we will have a problem.
return firewall
def _check_firewall_rule_conflict(self, fwr_db, fwp_db):
if not fwr_db['shared']:
if fwr_db['tenant_id'] != fwp_db['tenant_id']:
raise fw_ext.FirewallRuleConflict(
firewall_rule_id=fwr_db['id'],
tenant_id=fwr_db['tenant_id'])
def _set_rules_for_policy(self, context, firewall_policy_db, fwp):
rule_id_list = fwp['firewall_rules']
fwp_db = firewall_policy_db
with context.session.begin(subtransactions=True):
if not rule_id_list:
fwp_db.firewall_rules = []
fwp_db.audited = False
return
# We will first check if the new list of rules is valid
filters = {'id': [r_id for r_id in rule_id_list]}
rules_in_db = self._get_collection_query(context, FirewallRule,
filters=filters)
rules_dict = dict((fwr_db['id'], fwr_db) for fwr_db in rules_in_db)
for fwrule_id in rule_id_list:
if fwrule_id not in rules_dict:
# If we find an invalid rule in the list we
# do not perform the update since this breaks
# the integrity of this list.
raise fw_ext.FirewallRuleNotFound(
firewall_rule_id=fwrule_id)
elif rules_dict[fwrule_id]['firewall_policy_id']:
if (rules_dict[fwrule_id]['firewall_policy_id'] !=
fwp_db['id']):
raise fw_ext.FirewallRuleInUse(
firewall_rule_id=fwrule_id)
if 'shared' in fwp:
if fwp['shared'] and not rules_dict[fwrule_id]['shared']:
raise fw_ext.FirewallRuleSharingConflict(
firewall_rule_id=fwrule_id,
firewall_policy_id=fwp_db['id'])
elif fwp_db['shared'] and not rules_dict[fwrule_id]['shared']:
raise fw_ext.FirewallRuleSharingConflict(
firewall_rule_id=fwrule_id,
firewall_policy_id=fwp_db['id'])
for fwr_db in rules_in_db:
self._check_firewall_rule_conflict(fwr_db, fwp_db)
# New list of rules is valid so we will first reset the existing
# list and then add each rule in order.
# Note that the list could be empty in which case we interpret
# it as clearing existing rules.
fwp_db.firewall_rules = []
for fwrule_id in rule_id_list:
fwp_db.firewall_rules.append(rules_dict[fwrule_id])
fwp_db.firewall_rules.reorder()
fwp_db.audited = False
def _check_unshared_rules_for_policy(self, fwp_db, fwp):
if fwp['shared']:
rules_in_db = fwp_db['firewall_rules']
for fwr_db in rules_in_db:
if not fwr_db['shared']:
raise fw_ext.FirewallPolicySharingConflict(
firewall_rule_id=fwr_db['id'],
firewall_policy_id=fwp_db['id'])
def _process_rule_for_policy(self, context, firewall_policy_id,
firewall_rule_db, position):
with context.session.begin(subtransactions=True):
fwp_query = context.session.query(
FirewallPolicy).with_lockmode('update')
fwp_db = fwp_query.filter_by(id=firewall_policy_id).one()
if position:
# Note that although position numbering starts at 1,
# internal ordering of the list starts at 0, so we compensate.
fwp_db.firewall_rules.insert(position - 1, firewall_rule_db)
else:
fwp_db.firewall_rules.remove(firewall_rule_db)
fwp_db.firewall_rules.reorder()
fwp_db.audited = False
return self._make_firewall_policy_dict(fwp_db)
def _get_min_max_ports_from_range(self, port_range):
if not port_range:
return [None, None]
min_port, sep, max_port = port_range.partition(":")
if not max_port:
max_port = min_port
self._validate_fwr_port_range(min_port, max_port)
return [int(min_port), int(max_port)]
def _get_port_range_from_min_max_ports(self, min_port, max_port):
if not min_port:
return None
if min_port == max_port:
return str(min_port)
self._validate_fwr_port_range(min_port, max_port)
return '%s:%s' % (min_port, max_port)
def _validate_fw_parameters(self, context, fw, fw_tenant_id):
if 'firewall_policy_id' not in fw:
return
fwp_id = fw['firewall_policy_id']
fwp = self._get_firewall_policy(context, fwp_id)
if fw_tenant_id != fwp['tenant_id'] and not fwp['shared']:
raise fw_ext.FirewallPolicyConflict(firewall_policy_id=fwp_id)
def _validate_fwr_src_dst_ip_version(self, fwr):
src_version = dst_version = None
if fwr['source_ip_address']:
src_version = netaddr.IPNetwork(fwr['source_ip_address']).version
if fwr['destination_ip_address']:
dst_version = netaddr.IPNetwork(
fwr['destination_ip_address']).version
rule_ip_version = fwr['ip_version']
if ((src_version and src_version != rule_ip_version) or
(dst_version and dst_version != rule_ip_version)):
raise fw_ext.FirewallIpAddressConflict()
def _validate_fwr_port_range(self, min_port, max_port):
if int(min_port) > int(max_port):
port_range = '%s:%s' % (min_port, max_port)
raise fw_ext.FirewallRuleInvalidPortValue(port=port_range)
def _validate_fwr_protocol_parameters(self, fwr):
protocol = fwr['protocol']
if protocol not in (constants.PROTO_NAME_TCP,
constants.PROTO_NAME_UDP):
if fwr['source_port'] or fwr['destination_port']:
raise fw_ext.FirewallRuleInvalidICMPParameter(
param="Source, destination port")
def create_firewall(self, context, firewall, status=None):
LOG.debug("create_firewall() called")
fw = firewall['firewall']
tenant_id = fw['tenant_id']
# distributed routers may required a more complex state machine;
# the introduction of a new 'CREATED' state allows this, whilst
# keeping a backward compatible behavior of the logical resource.
if not status:
status = (p_const.CREATED if cfg.CONF.router_distributed
else p_const.PENDING_CREATE)
with context.session.begin(subtransactions=True):
self._validate_fw_parameters(context, fw, tenant_id)
firewall_db = Firewall(
id=uuidutils.generate_uuid(),
tenant_id=tenant_id,
name=fw['name'],
description=fw['description'],
firewall_policy_id=fw['firewall_policy_id'],
admin_state_up=fw['admin_state_up'],
status=status)
context.session.add(firewall_db)
return self._make_firewall_dict(firewall_db)
def update_firewall(self, context, id, firewall):
LOG.debug("update_firewall() called")
fw = firewall['firewall']
with context.session.begin(subtransactions=True):
fw_db = self.get_firewall(context, id)
self._validate_fw_parameters(context, fw, fw_db['tenant_id'])
count = context.session.query(Firewall).filter_by(id=id).update(fw)
if not count:
raise fw_ext.FirewallNotFound(firewall_id=id)
return self.get_firewall(context, id)
def update_firewall_status(self, context, id, status, not_in=None):
"""Conditionally update firewall status.
Status transition is performed only if firewall is not in the specified
states as defined by 'not_in' list.
"""
# filter in_ wants iterable objects, None isn't.
not_in = not_in or []
with context.session.begin(subtransactions=True):
return (context.session.query(Firewall).
filter(Firewall.id == id).
filter(~Firewall.status.in_(not_in)).
update({'status': status}, synchronize_session=False))
def delete_firewall(self, context, id):
LOG.debug("delete_firewall() called")
with context.session.begin(subtransactions=True):
# Note: Plugin should ensure that it's okay to delete if the
# firewall is active
count = context.session.query(Firewall).filter_by(id=id).delete()
if not count:
raise fw_ext.FirewallNotFound(firewall_id=id)
def get_firewall(self, context, id, fields=None):
LOG.debug("get_firewall() called")
fw = self._get_firewall(context, id)
return self._make_firewall_dict(fw, fields)
def get_firewalls(self, context, filters=None, fields=None):
LOG.debug("get_firewalls() called")
return self._get_collection(context, Firewall,
self._make_firewall_dict,
filters=filters, fields=fields)
def get_firewalls_count(self, context, filters=None):
LOG.debug("get_firewalls_count() called")
return self._get_collection_count(context, Firewall,
filters=filters)
def create_firewall_policy(self, context, firewall_policy):
LOG.debug("create_firewall_policy() called")
fwp = firewall_policy['firewall_policy']
with context.session.begin(subtransactions=True):
fwp_db = FirewallPolicy(id=uuidutils.generate_uuid(),
tenant_id=fwp['tenant_id'],
name=fwp['name'],
description=fwp['description'],
shared=fwp['shared'])
context.session.add(fwp_db)
self._set_rules_for_policy(context, fwp_db, fwp)
fwp_db.audited = fwp['audited']
return self._make_firewall_policy_dict(fwp_db)
def update_firewall_policy(self, context, id, firewall_policy):
LOG.debug("update_firewall_policy() called")
fwp = firewall_policy['firewall_policy']
with context.session.begin(subtransactions=True):
fwp_db = self._get_firewall_policy(context, id)
# check tenant ids are same for fw and fwp or not
if not fwp.get('shared', True) and fwp_db.firewalls:
for fw in fwp_db['firewalls']:
if fwp_db['tenant_id'] != fw['tenant_id']:
raise fw_ext.FirewallPolicyInUse(
firewall_policy_id=id)
# check any existing rules are not shared
if 'shared' in fwp and 'firewall_rules' not in fwp:
self._check_unshared_rules_for_policy(fwp_db, fwp)
elif 'firewall_rules' in fwp:
self._set_rules_for_policy(context, fwp_db, fwp)
del fwp['firewall_rules']
if 'audited' not in fwp:
fwp['audited'] = False
fwp_db.update(fwp)
return self._make_firewall_policy_dict(fwp_db)
def delete_firewall_policy(self, context, id):
LOG.debug("delete_firewall_policy() called")
with context.session.begin(subtransactions=True):
fwp = self._get_firewall_policy(context, id)
# Ensure that the firewall_policy is not
# being used
qry = context.session.query(Firewall)
if qry.filter_by(firewall_policy_id=id).first():
raise fw_ext.FirewallPolicyInUse(firewall_policy_id=id)
else:
context.session.delete(fwp)
def get_firewall_policy(self, context, id, fields=None):
LOG.debug("get_firewall_policy() called")
fwp = self._get_firewall_policy(context, id)
return self._make_firewall_policy_dict(fwp, fields)
def get_firewall_policies(self, context, filters=None, fields=None):
LOG.debug("get_firewall_policies() called")
return self._get_collection(context, FirewallPolicy,
self._make_firewall_policy_dict,
filters=filters, fields=fields)
def get_firewalls_policies_count(self, context, filters=None):
LOG.debug("get_firewall_policies_count() called")
return self._get_collection_count(context, FirewallPolicy,
filters=filters)
def create_firewall_rule(self, context, firewall_rule):
LOG.debug("create_firewall_rule() called")
fwr = firewall_rule['firewall_rule']
self._validate_fwr_protocol_parameters(fwr)
self._validate_fwr_src_dst_ip_version(fwr)
if not fwr['protocol'] and (fwr['source_port'] or
fwr['destination_port']):
raise fw_ext.FirewallRuleWithPortWithoutProtocolInvalid()
src_port_min, src_port_max = self._get_min_max_ports_from_range(
fwr['source_port'])
dst_port_min, dst_port_max = self._get_min_max_ports_from_range(
fwr['destination_port'])
with context.session.begin(subtransactions=True):
fwr_db = FirewallRule(
id=uuidutils.generate_uuid(),
tenant_id=fwr['tenant_id'],
name=fwr['name'],
description=fwr['description'],
shared=fwr['shared'],
protocol=fwr['protocol'],
ip_version=fwr['ip_version'],
source_ip_address=fwr['source_ip_address'],
destination_ip_address=fwr['destination_ip_address'],
source_port_range_min=src_port_min,
source_port_range_max=src_port_max,
destination_port_range_min=dst_port_min,
destination_port_range_max=dst_port_max,
action=fwr['action'],
enabled=fwr['enabled'])
context.session.add(fwr_db)
return self._make_firewall_rule_dict(fwr_db)
def update_firewall_rule(self, context, id, firewall_rule):
LOG.debug("update_firewall_rule() called")
fwr = firewall_rule['firewall_rule']
fwr_db = self._get_firewall_rule(context, id)
if fwr_db.firewall_policy_id:
fwp_db = self._get_firewall_policy(context,
fwr_db.firewall_policy_id)
if 'shared' in fwr and not fwr['shared']:
if fwr_db['tenant_id'] != fwp_db['tenant_id']:
raise fw_ext.FirewallRuleInUse(firewall_rule_id=id)
if 'source_port' in fwr:
src_port_min, src_port_max = self._get_min_max_ports_from_range(
fwr['source_port'])
fwr['source_port_range_min'] = src_port_min
fwr['source_port_range_max'] = src_port_max
del fwr['source_port']
if 'destination_port' in fwr:
dst_port_min, dst_port_max = self._get_min_max_ports_from_range(
fwr['destination_port'])
fwr['destination_port_range_min'] = dst_port_min
fwr['destination_port_range_max'] = dst_port_max
del fwr['destination_port']
with context.session.begin(subtransactions=True):
protocol = fwr.get('protocol', fwr_db['protocol'])
if not protocol:
sport = fwr.get('source_port_range_min',
fwr_db['source_port_range_min'])
dport = fwr.get('destination_port_range_min',
fwr_db['destination_port_range_min'])
if sport or dport:
raise fw_ext.FirewallRuleWithPortWithoutProtocolInvalid()
fwr_db.update(fwr)
if fwr_db.firewall_policy_id:
fwp_db.audited = False
return self._make_firewall_rule_dict(fwr_db)
def delete_firewall_rule(self, context, id):
LOG.debug("delete_firewall_rule() called")
with context.session.begin(subtransactions=True):
fwr = self._get_firewall_rule(context, id)
if fwr.firewall_policy_id:
raise fw_ext.FirewallRuleInUse(firewall_rule_id=id)
context.session.delete(fwr)
def get_firewall_rule(self, context, id, fields=None):
LOG.debug("get_firewall_rule() called")
fwr = self._get_firewall_rule(context, id)
return self._make_firewall_rule_dict(fwr, fields)
def get_firewall_rules(self, context, filters=None, fields=None):
LOG.debug("get_firewall_rules() called")
return self._get_collection(context, FirewallRule,
self._make_firewall_rule_dict,
filters=filters, fields=fields)
def get_firewalls_rules_count(self, context, filters=None):
LOG.debug("get_firewall_rules_count() called")
return self._get_collection_count(context, FirewallRule,
filters=filters)
def _validate_insert_remove_rule_request(self, id, rule_info):
if not rule_info or 'firewall_rule_id' not in rule_info:
raise fw_ext.FirewallRuleInfoMissing()
def insert_rule(self, context, id, rule_info):
LOG.debug("insert_rule() called")
self._validate_insert_remove_rule_request(id, rule_info)
firewall_rule_id = rule_info['firewall_rule_id']
insert_before = True
ref_firewall_rule_id = None
if not firewall_rule_id:
raise fw_ext.FirewallRuleNotFound(firewall_rule_id=None)
if 'insert_before' in rule_info:
ref_firewall_rule_id = rule_info['insert_before']
if not ref_firewall_rule_id and 'insert_after' in rule_info:
# If insert_before is set, we will ignore insert_after.
ref_firewall_rule_id = rule_info['insert_after']
insert_before = False
with context.session.begin(subtransactions=True):
fwr_db = self._get_firewall_rule(context, firewall_rule_id)
fwp_db = self._get_firewall_policy(context, id)
if fwr_db.firewall_policy_id:
raise fw_ext.FirewallRuleInUse(firewall_rule_id=fwr_db['id'])
self._check_firewall_rule_conflict(fwr_db, fwp_db)
if ref_firewall_rule_id:
# If reference_firewall_rule_id is set, the new rule
# is inserted depending on the value of insert_before.
# If insert_before is set, the new rule is inserted before
# reference_firewall_rule_id, and if it is not set the new
# rule is inserted after reference_firewall_rule_id.
ref_fwr_db = self._get_firewall_rule(
context, ref_firewall_rule_id)
if ref_fwr_db.firewall_policy_id != id:
raise fw_ext.FirewallRuleNotAssociatedWithPolicy(
firewall_rule_id=ref_fwr_db['id'],
firewall_policy_id=id)
if insert_before:
position = ref_fwr_db.position
else:
position = ref_fwr_db.position + 1
else:
# If reference_firewall_rule_id is not set, it is assumed
# that the new rule needs to be inserted at the top.
# insert_before field is ignored.
# So default insertion is always at the top.
# Also note that position numbering starts at 1.
position = 1
return self._process_rule_for_policy(context, id, fwr_db,
position)
def remove_rule(self, context, id, rule_info):
LOG.debug("remove_rule() called")
self._validate_insert_remove_rule_request(id, rule_info)
firewall_rule_id = rule_info['firewall_rule_id']
if not firewall_rule_id:
raise fw_ext.FirewallRuleNotFound(firewall_rule_id=None)
with context.session.begin(subtransactions=True):
fwr_db = self._get_firewall_rule(context, firewall_rule_id)
if fwr_db.firewall_policy_id != id:
raise fw_ext.FirewallRuleNotAssociatedWithPolicy(
firewall_rule_id=fwr_db['id'],
firewall_policy_id=id)
return self._process_rule_for_policy(context, id, fwr_db, None)
def migration_callback(resource, event, trigger, **kwargs):
context = kwargs['context']
router = kwargs['router']
fw_plugin = manager.NeutronManager.get_service_plugins().get(
p_const.FIREWALL)
if fw_plugin:
tenant_firewalls = fw_plugin.get_firewalls(
context, filters={'tenant_id': [router['tenant_id']]})
if tenant_firewalls:
raise l3.RouterInUse(router_id=router['id'])
def subscribe():
registry.subscribe(
migration_callback, resources.ROUTER, events.BEFORE_UPDATE)
# NOTE(armax): multiple FW service plugins (potentially out of tree) may
# inherit from firewall_db and may need the callbacks to be processed. Having
# an implicit subscription (through the module import) preserves the existing
# behavior, and at the same time it avoids fixing it manually in each and
# every fw plugin out there. That said, The subscription is also made
# explicitly in the reference fw plugin. The subscription operation is
# idempotent so there is no harm in registering the same callback multiple
# times.
subscribe()
neutron-fwaas-8.0.0/neutron_fwaas/db/cisco/ 0000775 0005670 0005671 00000000000 12701410073 022004 5 ustar jenkins jenkins 0000000 0000000 neutron-fwaas-8.0.0/neutron_fwaas/db/cisco/cisco_fwaas_db.py 0000664 0005670 0005671 00000004656 12701407720 025324 0 ustar jenkins jenkins 0000000 0000000 # Copyright 2015 Cisco Systems, 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.
from neutron.db import model_base
from oslo_log import helpers as log_helpers
import sqlalchemy as sa
class CiscoFirewallAssociation(model_base.BASEV2):
"""Represents FW association with CSR interface and attributes"""
__tablename__ = 'cisco_firewall_associations'
fw_id = sa.Column(sa.String(36),
sa.ForeignKey('firewalls.id', ondelete="CASCADE"),
primary_key=True)
port_id = sa.Column(sa.String(36),
sa.ForeignKey('ports.id', ondelete="CASCADE"))
direction = sa.Column(sa.String(16))
acl_id = sa.Column(sa.String(36))
router_id = sa.Column(sa.String(36))
class CiscoFirewall_db_mixin(object):
@log_helpers.log_method_call
def add_firewall_csr_association(self, context, fw):
with context.session.begin(subtransactions=True):
firewall_db = CiscoFirewallAssociation(fw_id=fw['id'],
port_id=fw['port_id'],
direction=fw['direction'],
acl_id=fw['acl_id'],
router_id=fw['router_id'])
context.session.add(firewall_db)
@log_helpers.log_method_call
def lookup_firewall_csr_association(self, context, fwid):
with context.session.begin(subtransactions=True):
csr_fw_qry = context.session.query(CiscoFirewallAssociation)
csr_fw = csr_fw_qry.filter_by(fw_id=fwid).first()
return csr_fw
@log_helpers.log_method_call
def update_firewall_csr_association(self, context, fwid, firewall):
with context.session.begin(subtransactions=True):
csr_fw_qry = context.session.query(CiscoFirewallAssociation)
csr_fw = csr_fw_qry.filter_by(fw_id=fwid).first()
csr_fw.update(firewall)
return firewall
neutron-fwaas-8.0.0/neutron_fwaas/db/cisco/__init__.py 0000664 0005670 0005671 00000000000 12701407720 024110 0 ustar jenkins jenkins 0000000 0000000 neutron-fwaas-8.0.0/neutron_fwaas/db/__init__.py 0000664 0005670 0005671 00000000000 12701407720 023010 0 ustar jenkins jenkins 0000000 0000000 neutron-fwaas-8.0.0/neutron_fwaas/db/migration/ 0000775 0005670 0005671 00000000000 12701410073 022675 5 ustar jenkins jenkins 0000000 0000000 neutron-fwaas-8.0.0/neutron_fwaas/db/migration/__init__.py 0000664 0005670 0005671 00000000000 12701407720 025001 0 ustar jenkins jenkins 0000000 0000000 neutron-fwaas-8.0.0/neutron_fwaas/db/migration/alembic_migrations/ 0000775 0005670 0005671 00000000000 12701410073 026525 5 ustar jenkins jenkins 0000000 0000000 neutron-fwaas-8.0.0/neutron_fwaas/db/migration/alembic_migrations/README 0000664 0005670 0005671 00000000046 12701407720 027412 0 ustar jenkins jenkins 0000000 0000000 Generic single-database configuration. neutron-fwaas-8.0.0/neutron_fwaas/db/migration/alembic_migrations/env.py 0000664 0005670 0005671 00000004655 12701407720 027706 0 ustar jenkins jenkins 0000000 0000000 # Copyright 2014 OpenStack Foundation
#
# 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.
from logging import config as logging_config
from alembic import context
from neutron.db import model_base
from oslo_config import cfg
from oslo_db.sqlalchemy import session
import sqlalchemy as sa
from sqlalchemy import event
MYSQL_ENGINE = None
FWAAS_VERSION_TABLE = 'alembic_version_fwaas'
config = context.config
neutron_config = config.neutron_config
logging_config.fileConfig(config.config_file_name)
target_metadata = model_base.BASEV2.metadata
def set_mysql_engine():
try:
mysql_engine = neutron_config.command.mysql_engine
except cfg.NoSuchOptError:
mysql_engine = None
global MYSQL_ENGINE
MYSQL_ENGINE = (mysql_engine or
model_base.BASEV2.__table_args__['mysql_engine'])
def run_migrations_offline():
set_mysql_engine()
kwargs = dict()
if neutron_config.database.connection:
kwargs['url'] = neutron_config.database.connection
else:
kwargs['dialect_name'] = neutron_config.database.engine
kwargs['version_table'] = FWAAS_VERSION_TABLE
context.configure(**kwargs)
with context.begin_transaction():
context.run_migrations()
@event.listens_for(sa.Table, 'after_parent_attach')
def set_storage_engine(target, parent):
if MYSQL_ENGINE:
target.kwargs['mysql_engine'] = MYSQL_ENGINE
def run_migrations_online():
set_mysql_engine()
engine = session.create_engine(neutron_config.database.connection)
connection = engine.connect()
context.configure(
connection=connection,
target_metadata=target_metadata,
version_table=FWAAS_VERSION_TABLE
)
try:
with context.begin_transaction():
context.run_migrations()
finally:
connection.close()
engine.dispose()
if context.is_offline_mode():
run_migrations_offline()
else:
run_migrations_online()
neutron-fwaas-8.0.0/neutron_fwaas/db/migration/alembic_migrations/versions/ 0000775 0005670 0005671 00000000000 12701410073 030375 5 ustar jenkins jenkins 0000000 0000000 neutron-fwaas-8.0.0/neutron_fwaas/db/migration/alembic_migrations/versions/kilo_release.py 0000664 0005670 0005671 00000001512 12701407720 033411 0 ustar jenkins jenkins 0000000 0000000 # 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.
#
"""kilo
Revision ID: kilo
Revises: 796c68dffbb
Create Date: 2015-04-16 00:00:00.000000
"""
# revision identifiers, used by Alembic.
revision = 'kilo'
down_revision = '796c68dffbb'
def upgrade():
"""A no-op migration for marking the Kilo release."""
pass
neutron-fwaas-8.0.0/neutron_fwaas/db/migration/alembic_migrations/versions/mitaka/ 0000775 0005670 0005671 00000000000 12701410073 031643 5 ustar jenkins jenkins 0000000 0000000 neutron-fwaas-8.0.0/neutron_fwaas/db/migration/alembic_migrations/versions/mitaka/contract/ 0000775 0005670 0005671 00000000000 12701410073 033460 5 ustar jenkins jenkins 0000000 0000000 ././@LongLink 0000000 0000000 0000000 00000000171 00000000000 011214 L ustar 0000000 0000000 neutron-fwaas-8.0.0/neutron_fwaas/db/migration/alembic_migrations/versions/mitaka/contract/458aa42b14b_fw_table_alter.py neutron-fwaas-8.0.0/neutron_fwaas/db/migration/alembic_migrations/versions/mitaka/contract/458aa42b10000664 0005670 0005671 00000002562 12701407720 034630 0 ustar jenkins jenkins 0000000 0000000 #Copyright 2015 OpenStack Foundation
#
# 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.
#
"""fw_table_alter script to make column case sensitive
Revision ID: 458aa42b14b
Revises: 67c8e8d61d5
Create Date: 2015-09-16 11:47:43.061649
"""
from alembic import op
from neutron.db import migration
# revision identifiers, used by Alembic.
revision = '458aa42b14b'
down_revision = '67c8e8d61d5'
# milestone identifier, used by neutron-db-manage
neutron_milestone = [migration.MITAKA]
FW_TAB_NAME = ['firewall_rules', 'firewall_policies', 'firewalls']
SQL_STATEMENT_UPDATE_CMD = (
"alter table %s "
"modify name varchar(255) "
"CHARACTER SET utf8 COLLATE utf8_bin"
)
def upgrade():
context = op.get_context()
if context.bind.dialect.name == 'mysql':
for table in FW_TAB_NAME:
op.execute(SQL_STATEMENT_UPDATE_CMD % table)
././@LongLink 0000000 0000000 0000000 00000000152 00000000000 011213 L ustar 0000000 0000000 neutron-fwaas-8.0.0/neutron_fwaas/db/migration/alembic_migrations/versions/796c68dffbb_cisco_csr_fwaas.py neutron-fwaas-8.0.0/neutron_fwaas/db/migration/alembic_migrations/versions/796c68dffbb_cisco_csr_fwa0000664 0005670 0005671 00000003012 12701407720 035037 0 ustar jenkins jenkins 0000000 0000000 # Copyright 2015 OpenStack Foundation
#
# 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.
#
"""cisco_csr_fwaas
Revision ID: 796c68dffbb
Revises: 540142f314f4
Create Date: 2015-02-02 13:11:55.184112
"""
# revision identifiers, used by Alembic.
revision = '796c68dffbb'
down_revision = '540142f314f4'
from alembic import op
import sqlalchemy as sa
def upgrade(active_plugins=None, options=None):
op.create_table('cisco_firewall_associations',
sa.Column('fw_id', sa.String(length=36), nullable=False),
sa.Column('port_id', sa.String(length=36), nullable=True),
sa.Column('direction', sa.String(length=16), nullable=True),
sa.Column('acl_id', sa.String(length=36), nullable=True),
sa.Column('router_id', sa.String(length=36), nullable=True),
sa.ForeignKeyConstraint(['fw_id'], ['firewalls.id'],
ondelete='CASCADE'),
sa.ForeignKeyConstraint(['port_id'], ['ports.id'],
ondelete='CASCADE'),
sa.PrimaryKeyConstraint('fw_id')
)
neutron-fwaas-8.0.0/neutron_fwaas/db/migration/alembic_migrations/versions/CONTRACT_HEAD 0000664 0005670 0005671 00000000014 12701407720 032316 0 ustar jenkins jenkins 0000000 0000000 458aa42b14b
neutron-fwaas-8.0.0/neutron_fwaas/db/migration/alembic_migrations/versions/start_neutron_fwaas.py 0000664 0005670 0005671 00000001533 12701407720 035046 0 ustar jenkins jenkins 0000000 0000000 # Copyright 2014 OpenStack Foundation
#
# 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.
#
"""start neutron-fwaas chain
Revision ID: start_neutron_fwaas
Revises: None
Create Date: 2014-12-09 18:42:08.262632
"""
# revision identifiers, used by Alembic.
revision = 'start_neutron_fwaas'
down_revision = None
def upgrade():
pass
neutron-fwaas-8.0.0/neutron_fwaas/db/migration/alembic_migrations/versions/EXPAND_HEAD 0000664 0005670 0005671 00000000015 12701407720 032061 0 ustar jenkins jenkins 0000000 0000000 4b47ea298795
neutron-fwaas-8.0.0/neutron_fwaas/db/migration/alembic_migrations/versions/liberty/ 0000775 0005670 0005671 00000000000 12701410073 032047 5 ustar jenkins jenkins 0000000 0000000 neutron-fwaas-8.0.0/neutron_fwaas/db/migration/alembic_migrations/versions/liberty/contract/ 0000775 0005670 0005671 00000000000 12701410073 033664 5 ustar jenkins jenkins 0000000 0000000 ././@LongLink 0000000 0000000 0000000 00000000163 00000000000 011215 L ustar 0000000 0000000 neutron-fwaas-8.0.0/neutron_fwaas/db/migration/alembic_migrations/versions/liberty/contract/67c8e8d61d5_initial.py neutron-fwaas-8.0.0/neutron_fwaas/db/migration/alembic_migrations/versions/liberty/contract/67c8e8d60000664 0005670 0005671 00000002023 12701407720 034767 0 ustar jenkins jenkins 0000000 0000000 # Copyright 2015 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.
#
"""Initial Liberty no-op script.
Revision ID: 67c8e8d61d5
Revises: kilo
Create Date: 2015-07-28 22:18:13.330846
"""
from neutron.db import migration
from neutron.db.migration import cli
# revision identifiers, used by Alembic.
revision = '67c8e8d61d5'
down_revision = 'kilo'
branch_labels = (cli.CONTRACT_BRANCH,)
# milestone identifier, used by neutron-db-manage
neutron_milestone = [migration.LIBERTY]
def upgrade():
pass
neutron-fwaas-8.0.0/neutron_fwaas/db/migration/alembic_migrations/versions/liberty/expand/ 0000775 0005670 0005671 00000000000 12701410073 033326 5 ustar jenkins jenkins 0000000 0000000 ././@LongLink 0000000 0000000 0000000 00000000161 00000000000 011213 L ustar 0000000 0000000 neutron-fwaas-8.0.0/neutron_fwaas/db/migration/alembic_migrations/versions/liberty/expand/c40fbb377ad_initial.py neutron-fwaas-8.0.0/neutron_fwaas/db/migration/alembic_migrations/versions/liberty/expand/c40fbb377a0000664 0005670 0005671 00000001625 12701407720 034724 0 ustar jenkins jenkins 0000000 0000000 # Copyright 2015 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.
#
"""Initial Liberty no-op script.
Revision ID: c40fbb377ad
Revises: kilo
Create Date: 2015-07-28 22:18:13.321233
"""
from neutron.db.migration import cli
# revision identifiers, used by Alembic.
revision = 'c40fbb377ad'
down_revision = 'kilo'
branch_labels = (cli.EXPAND_BRANCH,)
def upgrade():
pass
././@LongLink 0000000 0000000 0000000 00000000172 00000000000 011215 L ustar 0000000 0000000 neutron-fwaas-8.0.0/neutron_fwaas/db/migration/alembic_migrations/versions/liberty/expand/4b47ea298795_add_reject_rule.py neutron-fwaas-8.0.0/neutron_fwaas/db/migration/alembic_migrations/versions/liberty/expand/4b47ea29870000664 0005670 0005671 00000002253 12701407720 034600 0 ustar jenkins jenkins 0000000 0000000 # Copyright 2015 NEC Corporation. All rights reserved.
#
# 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.
"""add reject rule
Revision ID: 4b47ea298795
Revises: c40fbb377ad
Create Date: 2015-04-15 04:19:57.324584
"""
from alembic import op
import sqlalchemy as sa
from neutron.db import migration
# revision identifiers, used by Alembic.
revision = '4b47ea298795'
down_revision = 'c40fbb377ad'
# milestone identifier, used by neutron-db-manage
neutron_milestone = [migration.LIBERTY, migration.MITAKA]
new_action = sa.Enum('allow', 'deny', 'reject', name='firewallrules_action')
def upgrade():
op.alter_column('firewall_rules', 'action', type_=new_action)
././@LongLink 0000000 0000000 0000000 00000000162 00000000000 011214 L ustar 0000000 0000000 neutron-fwaas-8.0.0/neutron_fwaas/db/migration/alembic_migrations/versions/540142f314f4_fwaas_router_insertion.py neutron-fwaas-8.0.0/neutron_fwaas/db/migration/alembic_migrations/versions/540142f314f4_fwaas_router0000664 0005670 0005671 00000003042 12701407720 034474 0 ustar jenkins jenkins 0000000 0000000 # Copyright 2014 OpenStack Foundation
#
# 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.
#
"""FWaaS router insertion
Revision ID: 540142f314f4
Revises: 4202e3047e47
Create Date: 2015-02-06 17:02:24.279337
"""
# revision identifiers, used by Alembic.
revision = '540142f314f4'
down_revision = '4202e3047e47'
from alembic import op
import sqlalchemy as sa
SQL_STATEMENT = (
"insert into firewall_router_associations "
"select "
"f.id as fw_id, r.id as router_id "
"from firewalls f, routers r "
"where "
"f.tenant_id=r.tenant_id"
)
def upgrade():
op.create_table('firewall_router_associations',
sa.Column('fw_id', sa.String(length=36), nullable=False),
sa.Column('router_id', sa.String(length=36), nullable=False),
sa.ForeignKeyConstraint(['fw_id'], ['firewalls.id'],
ondelete='CASCADE'),
sa.ForeignKeyConstraint(['router_id'], ['routers.id'],
ondelete='CASCADE'),
sa.PrimaryKeyConstraint('fw_id', 'router_id'),
)
op.execute(SQL_STATEMENT)
././@LongLink 0000000 0000000 0000000 00000000157 00000000000 011220 L ustar 0000000 0000000 neutron-fwaas-8.0.0/neutron_fwaas/db/migration/alembic_migrations/versions/4202e3047e47_add_index_tenant_id.py neutron-fwaas-8.0.0/neutron_fwaas/db/migration/alembic_migrations/versions/4202e3047e47_add_index_te0000664 0005670 0005671 00000002103 12701407720 034402 0 ustar jenkins jenkins 0000000 0000000 # Copyright 2015 OpenStack Foundation
#
# 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.
#
"""add_index_tenant_id
Revision ID: 4202e3047e47
Revises: start_neutron_fwaas
Create Date: 2015-02-10 17:17:47.846764
"""
# revision identifiers, used by Alembic.
revision = '4202e3047e47'
down_revision = 'start_neutron_fwaas'
from alembic import op
TABLES = ['firewall_rules', 'firewalls', 'firewall_policies']
def upgrade():
for table in TABLES:
op.create_index(op.f('ix_%s_tenant_id' % table),
table, ['tenant_id'], unique=False)
neutron-fwaas-8.0.0/neutron_fwaas/db/migration/alembic_migrations/script.py.mako 0000664 0005670 0005671 00000002035 12701407720 031336 0 ustar jenkins jenkins 0000000 0000000 # Copyright ${create_date.year}
#
# 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.
#
"""${message}
Revision ID: ${up_revision}
Revises: ${down_revision}
Create Date: ${create_date}
"""
# revision identifiers, used by Alembic.
revision = ${repr(up_revision)}
down_revision = ${repr(down_revision)}
% if branch_labels:
branch_labels = ${repr(branch_labels)}
%endif
from alembic import op
import sqlalchemy as sa
${imports if imports else ""}
def upgrade():
${upgrades if upgrades else "pass"}
neutron-fwaas-8.0.0/LICENSE 0000664 0005670 0005671 00000023637 12701407720 016471 0 ustar jenkins jenkins 0000000 0000000
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
neutron-fwaas-8.0.0/ChangeLog 0000664 0005670 0005671 00000114522 12701410072 017222 0 ustar jenkins jenkins 0000000 0000000 CHANGES
=======
8.0.0
-----
* Constraint requirements using mitaka upper-constraints.txt file
8.0.0.0rc2
----------
* Update .gitreview for stable/mitaka
8.0.0.0rc1
----------
* Use routers client instead of networks client
* Use tempest.lib base module for network
* Updated from global requirements
* Make all tox targets constrained
* Tag the alembic migration revisions for Mitaka
8.0.0.0b3
---------
* FWaaS: make use of neutron_lib constants
* Use tempest.lib instead of tempest-lib
* Track alembic heads
* Remove unused pngmath Sphinx extension
* Fixed typo in subunit-trace.py
* Updated from global requirements
* Select the right DB to store user and data in each backend
* Modify tox.ini to run dsvm-functional tests
* Updated from global requirements
* delete meaningless braces in log
* Updated from global requirements
* Cleanup i18n module usages
* tempest: Confirm the opposite direction
* tempest: Fix a few test cases
* FWaaS quota registration
* Add testresources to neutron-fwaas test requirements
* Fix neutron-fwaas cover tests
* Send Notifications for Firewall policy updates
* Set testenv env for api and scenario testing
* tempest: Skips router insertion tests if public_router_id is configured
* tempest: Update for NetworkClient
* Add an explicit BRANCH_NAME to tox_install.sh
* Update translation setup
* tempest: Add a comment
* Updated from global requirements
* tempest: Remove an extra comma, which breaks the following assertion
* Add unittest of convert_action_to_case_insensitive
* Updated from global requirements
8.0.0.0b2
---------
* Clean up removed hacking rule from [flake8] ignore lists
* tempest: Add test cases for router insertion
* Replace deprecated library function os.popen() with subprocess
* Add unit test for convert_protocol
* Updated from global requirements
* Change LOG.warn to LOG.warning
* LOG.warn -> LOG.warning
* Trival: Remove unused logging import
* tempest: Update after the recent tempest change
* Updated from global requirements
* Avoid duplicating tenant check when creating resources
* Fix a typo from UPPER_CONTRAINTS_FILE to UPPER_CONSTRAINTS_FILE
* Setup for translation
* Deprecated tox -downloadcache option removed
* Remove Neutron FWaaS static example configuration files
* Updated from global requirements
* Added constraints tox targets
* Automatically generate neutron FWaaS configuration files
* Adapt to the recent tempest
* Delete python bytecode before every test run
* Updated from global requirements
* Remove dependency on neutron for topics
* Add reno for release notes management
* Fix db error when running python34 Unit tests
* Remove version from setup.cfg
8.0.0.0b1
---------
* Fix TempestPlugin to fix gate failure
* Freescale FWaaS Plugin code final decomposition
* Updated from global requirements
* Add some more tempest scenarios
* Updated from global requirements
* Set ZUUL_BRANCH using BRANCH if not available
* Move api tests from Neutron repository
* Revert "Register FWaaS resources to quota engine"
* Remove deprecated use_namespaces option
* Prepare neutron "use_namespaces" option removal
* Update list of modules supporting py34 tests
* FWaaS fix comment typos
* Updated from global requirements
* Updated from global requirements
* Add tempest scenario tests
* Updated from global requirements
* Removed new=True argument from create_connection
* Include alembic versions directory to the package
* Register FWaaS resources to quota engine
* Updated from global requirements
* Validate src_ip_adress, dest_ip_address and ip_version
* Updated from global requirements
* Use assert(Not)In instead of assertTrue/False
* use assertIs(Not)None instead of assert(Not)Equal
* use assertFalse instead of assertEqual(False, ***)
* Fix argument order for assertEqual to (expected, observed)
* Case-Sensitivity for name column in fw table
7.0.0
-----
* Tag the alembic migration revisions for Liberty
* Tag the alembic migration revisions for Liberty
* Consume FWaaS plugin queue in RPC workers
* Kill HEADS file
* Stop doing any magic cloning of neutron during CI
* Use stable/liberty branch for neutron dep
7.0.0.0rc1
----------
* Update defaultbranch in .gitreview to stable/liberty
* Open Mitaka development
* Change ignore-errors to ignore_errors
* Updated from global requirements
* Fix check_migration error
* Added +x permission to gate hook scripts
* py34 support for fwaas
7.0.0.0b3
---------
* Updated from global requirements
* Updated from global requirements
* Removing unused dependency: discover
* Kill contention between update and delete
* FWaaS: Fix 500 INTERNAL error on too long name or description
* Adopt the migration chaining and branch names from neutron
* Switch to using os-testr's copy of subunit2html
* Cisco CSR FWaaS driver should use 'l4-options' in CSR RESTAPI call
* Updated from global requirements
* Add REJECT rule on Neutron FWaaS
* Make tests/unit/extensions discoverable
* Updated from global requirements
* Reduce contention between update and delete
* Add oslotest dependency to test-requirements
* Updated from global requirements
* Validate tenant_id between firewall and firewall-policy
* Do not make delete_db_firewall conditional
* Updated from global requirements
* switch to multi branch migration tree for liberty
* py34: Enable initial python34 testing for FWaaS
* Killed existing downgrade rules in migration scripts
7.0.0.0b2
---------
* script.py.mako: update to latest standards
* py34: Fix usage of gettext.install
* Register alembic_migrations at install time
* Updated from global requirements
* Remove quantum untracked files from .gitignore
* Fix wrong argument name in _rpc_update_firewall
* Use oslo_log.helpers.log_method_call
* Updated from global requirements
* Fix UT failures during firewall mock plugin setup
* COMMON_PREFIXES cleanup - patch 3/5
* Updated from global requirements
* Switch to oslo.service
7.0.0.0b1
---------
* Updated from global requirements
* Switch to oslo_utils.uuidutils
* Fixes firewall going to error state on an update
* Trim some unused test packages
* Update version for Liberty
* Updated from global requirements
* Add handle for protocol value "any" in CSR1kv driver
7.0.0a0
-------
* Updated from global requirements
* Revert "Insert tenant_id validation for fw and fw-policy"
* Updated from global requirements
* Python 3: use six.iteritems instead of dict.items
* Enable random hash seeds
* Do not assume jsonutils.dumps ordering
* Updated from global requirements
* Add validation of port_range for firewall-rule
* Remove contextlib.nested from tests
* vendor code should refer to Brocade
* Updated from global requirements
* Make iptables firewall work with L3 plugin without DVR support
* Updated from global requirements
* Insert tenant_id validation for fw and fw-policy
2015.1.0
--------
* Insert validation in creating/updating firewall
* update .gitreview for stable/kilo
* Updated Protocol named constants
* Add Kilo release milestone
* Add Kilo release milestone
* Pin neutron to stable/kilo
* Restore Brocade Vyatta firewall functionality
* FWaaS: Remove check for bash usage
* Restore Brocade Vyatta firewall functionality
* Switch from neutron.common.log.log to oslo_log.helpers.log_method_call
* logic error in updating audited of firewall policy
2015.1.0rc1
-----------
* FWaaS: Reorganize unit test tree
* Open Liberty development
* Updated Protocol named constants
* FWaaS: Refactor callback mechanism
* Use BaseSudoTestCase instead of BaseLinuxTestCase
* Remove reference to testlib_plugin
* Updated from global requirements
2015.1.0b3
----------
* Adding mandatory parameters for Router Info in vArmour fwaas agent
* tests: stop overwriting neutron BaseTestCase configuration files
* Refactoring related to 'FWaaS insertion Model on Routers'
* Adds FWaaS driver for Cisco CSR1kv
* Adds FWaaS service plugin for Cisco CSR1kv
* FWaaS Insertion Model on Routers
* Decouple L3 and Firewall during DVR router migration
* Implementation of Mcafee NGFW Driver
* Provide hooks for FWaaS repo functional gate
* Updated from global requirements
* Fix for breaking UTs when creating RouterInfo
* Add the missing parameter agent_mode to the FWaaSDriverBase class methods
* Add the prefix networking_brocade to import paths
* Pick up missing neutron to neuton_fwaas change
* Removed lockutils-wrapper from tox targets
* Migrate to oslo.log
* Change L3 agent AdvancedService class to be non-singleton
* Updated from global requirements
* Enable removing references to self.services_sync in l3 agent
* Stop storing and passing root_helper
* Fix pylint error due to novaclient v1_1/v2 rename
* Add index on tenant_id
* FWaaS: Enable coverage testing
* Remove unused _destroy_router_namespaces()
* Implementation of Brocade Vyatta Firewall driver
* Pass root_helper to ip_lib by keyword argument to prep for removal
* Fixed tests to use neutron_fwaas extensions and neutrons
* oslo: migrate to namespace-less import paths
2015.1.0b2
----------
* Code cleanup for Freescale FWaaS Plugin
* Updated from global requirements
* Move extensions to service repo
* Fix neutron-fwaas unit test failures due to multiple issues
* Move '_make_firewall_dict_with_rules' to firewall_db.py
* Freescale FWaaS Plugin
* Updated from global requirements
* Updated from global requirements
* Updated from global requirements
* Migrate to oslo.concurrency
* Adjust fwaas unit tests to work with quotas enabled
* Updated from global requirements
* Update hacking to 0.10
* Fix the neutron-fwaas unit test failures
* Updated from global requirements
* FWaaS: L3 Agent restructure - observer hierarchy
* Cleaned up requirements.txt
* Bump from global requirements
* Fix gitignore of egg files properly
* Do not list neutron in requirements.txt
* Re-enable UT for neutron-fwaas for services split
* Backward compatibility for fwaas
* Update documentation files for FWaaS
2015.1.0b1
----------
* Kill oslo-incubator files
* Move classes out of l3_agent.py
* Delete accidentally committed egg files
* Fix python path to neutron_fwaas module
* Init of separate alembic chain
* Fix python path in ini file
* After the services split, get neutron-fwaas Jenkins jobs passing
* Fix git review target for repo
* Split fwaas services code into neutron-fwaas
* Workflow documentation is now in infra-manual
* tox.ini: Prevent casual addition of bash dependency
* Updated from global requirements
* Get rid of py26 references: OrderedDict, httplib, xml testing
* Updated the README.rst
* pretty_tox.sh: Portablity improvement
* test_dhcp_agent: Fix no-op tests
* Enable undefined-loop-variable pylint check
* Fix incorrect exception order in _execute_request
* Migrate to oslo.i18n
* Migrate to oslo.middleware
* Migrate to oslo.utils
* Remove Python 2.6 classifier
* Remove ryu plugin
* Updated from global requirements
* Fix AttributeError in RPC code for DVR
* Show progress output while running unit tests
* Enforce log hints in neutron.services.firewall
* enable H401 hacking check
* enable H237 check
* Updated from global requirements
* Drop RpcProxy usage from FWaaS code
* Drop several uses of RpcCallback
* Enable default SNAT from networks connected to a router indirectly
* Updated from global requirements
* Update i18n translation for neutron.db log msg's
* Update i18n translation for neutron.agents log msg's
* enable F812 check for flake8
* enable F811 check for flake8
* Support pudb as a different post mortem debugger
* switch to oslo.serialization
* Add rootwrap filters for ofagent
* Remove useless return
* Remove openvswitch core plugin entry point
* Updated from global requirements
* Purge use of "PRED and A or B" poor-mans-ternary
* Remove duplicate ensure_remove_chain method in iptables_manager
* Remove use_namespaces from RouterInfo Property
* Updated from global requirements
* Remove XML support
* enable F402 check for flake8
* enable E713 in pep8 tests
* Hyper-V: Remove useless use of "else" clause on for loop
* Enable no-name-in-module pylint check
* Updated from global requirements
* Remove duplicate import of constants module
* Switch run-time import to using importutils.import_module
* Enable assignment-from-no-return pylint check
* tox.ini: Avoid using bash where unnecessary
* Empty files should not contain copyright or license
* Remove single occurrence of lost-exception warning
* Updated fileutils and its dependencies
* remove E251 exemption from pep8 check
* mock.assert_called_once() is not a valid method
* Add pylint tox environment and disable all existing warnings
* Updated from global requirements
* Ignore top-level hidden dirs/files by default
* Avoid constructing a RouterInfo object to get namespace name
* Drop sslutils and versionutils modules
* Removed kombu from requirements
* Updated from global requirements
* Updated from global requirements
* Remove sslutils from openstack.common
* remove linuxbridge plugin
* Open Kilo development
* Implement ModelsMigrationsSync test from oslo.db
* Disallow unsharing used firewall policy
* Fix entrypoint of OneConvergencePlugin plugin
* Stop admin using other tenants unshared rules
* Set dsvm-functional job to use system packages
* Separate Configuration from Freescale SDN ML2 mechanism Driver
* Remove @author(s) from copyright statements
* Add HA support to the l3 agent
* Updated from global requirements
* Adds ipset support for Security Groups
* Remove useless check in _rpc_update_firewall
* Don't allow user to set firewall rule with port and no protocol
* Changes to support FWaaS in a DVR based environment
* Add requests_mock to test-requirements.txt
* Removed kombu from requirements
* Supply missing cisco_cfg_agent.ini file
* Remove unused arg to config.setup_logging()
* Updated from global requirements
* shared policy shouldn't have unshared rules
* Work toward Python 3.4 support and testing
* Revert "Cisco DFA ML2 Mechanism Driver"
* Remove SELECT FOR UPDATE use in delete_firewall
* Big Switch: Separate L3 functions into L3 service
* Remove reference to cisco_cfg_agent.ini from setup.cfg again
* Adds router service plugin for CSR1kv
* Support for extensions in ML2
* Cisco DFA ML2 Mechanism Driver
* Adding mechanism driver in ML2 plugin for Nuage Networks
* Fix state_path in tests
* Remove ovs dependency in embrane plugin
* Use lockutils module for tox functional env
* Remove SELECT FOR UPDATE use in update_firewall
* Prefer "val !=/== ref" over "val (not) in [ref]" in conditions
* Remove status initialization from plugin's create_firewall
* Set firewall state to CREATED when dealing with DVR
* Updated from global requirements
* Add specific docs build option to tox
* Fix bigswitch setup.cfg lines
* Remove auto-generation of db schema from models at startup
* Skip FWaaS config mismatch check if RPC method is unsupported
* Updated from global requirements
* Use jsonutils instead of stdlib json
* Remove INACTIVE status from FWaaS
* Preserve link local IP allocations for DVR fip ns across restart
* Opencontrail plug-in implementation for core resources
* Return 403 instead of 404 on attr policy failures
* Proper validation for inserting firewall rule
* Remove redundant topic from rpc calls
* Add a tox test environment for random hashseed testing
* Updated from global requirements
* Move from Python logging to Openstack logging
* Remove reference to cisco_cfg_agent.ini from setup.cfg
* Exit Firewall Agent if config is invalid
* Removed configobj from test requirements
* Updated from global requirements
* Functional tests work fine with random PYTHONHASHSEED
* Set python hash seed to 0 in tox.ini
* Configuration agent for Cisco devices
* Updated from global requirements
* ML2 mechanism driver for SR-IOV capable NIC based switching, Part 2
* Audited attribute for policy update not changing
* This patch changes the name of directory from mech_arista to arista
* ML2 mechanism driver for SR-IOV capable NIC based switching, Part 1
* Allow to import _LC, _LE, _LI and _LW functions directly
* Make readme reference git.openstack.org not github
* Bump hacking to version 0.9.2
* Use auth_token from keystonemiddleware
* Change all occurences of no_delete to do_delete
* Extract CommonDBMixin to a separate file
* Remove reference to setuptools_git
* Add a gate-specific tox env for functional tests
* Add CONTRIBUTING.rst
* Updated from global requirements
* Updated from global requirements
* Updated from global requirements
* Fix example for running individual tests
* Switch to using of oslo.db
* remove unsupported middleware
* Add config for performance gate job
* Synced log module and its dependencies from olso-incubator
* don't ignore rules that are already enforced
* Moved rpc_compat.py code back into rpc.py
* Updated from global requirements
* Updated from global requirements
* ofagent: move main module from ryu repository
* Remove the useless vim modelines
* Removed 'rpc' and 'notifier' incubator modules
* Removed create_rpc_dispatcher methods
* Use openstack.common.lockutils module for locks in tox functional tests
* Renamed consume_in_thread -> consume_in_threads
* Port to oslo.messaging
* Updated from global requirements
* Ignore emacs checkpoint files
* Check port value when creating firewall rule with icmp protocol
* Configure agents using neutron.common.config.init (formerly .parse)
* Added missing core_plugins symbolic names
* Introduced rpc_compat.create_connection()
* Introduce RpcCallback class
* remove pep8 E122 exemption and correct style
* remove E112 hacking exemption and fix errors
* Updated from global requirements
* Fix race condition with firewall deletion
* Monkey patch threading module as early as possible
* Added RpcProxy class
* Freescale SDN Mechanism Driver for ML2 Plugin
* Remove run-time version checking for openvswitch features
* Log firewall status on delete in case of status inconsistency
* Added missing plugin .ini files to setup.cfg
* FWaaS plugin doesn't need to handle firewall rule del ops
* Updated from global requirements
* Disallow regular user to update firewall's shared attribute
* Synced jsonutils from oslo-incubator
* Cisco APIC ML2 mechanism driver, part 2
* NSX: get rid of the last Nicira/NVP bits
* Do not defer IPTables apply in firewall path
* Fix non-existent 'assert' calls to mocks
* Add missing translation support
* Add mailmap entry
* Updated from global requirements
* Remove explicit dependency on amqplib
* Remove duplicate module-rgx line in .pylintrc
* Fix H302 violations
* Fix H302 violations in unit tests
* Updated from global requirements
* Updated from global requirements
* Exclude .ropeproject from flake8 checks
* Remove mock.patch.stop from tests that inherit from BaseTestCase
* Enable flake8 E711 and E712 checking
* Updated from global requirements
* Sync service and systemd modules from oslo-incubator
* Move bash whitelisting to pep8 testenv
* Fix Jenkins translation jobs
* Set ns_name in RouterInfo as attribute
* ignore build directory for pep8
* Return 409 for second firewall creation
* Enable hacking H301 check
* Updated from global requirements
* Remove last parts of Quantum compatibility shim
* UT: do not hide an original error in test resource ctxtmgr
* Open Juno development
* Start using oslosphinx theme for docs
* Updated from global requirements
* add HEAD sentinel file that contains migration revision
* Ensure to count firewalls in target tenant
* Mock agent RPC for FWaaS tests to delete DB objs
* Fix KeyError except on router_info in FW Agent
* Bugfix and refactoring for ovs_lib flow methods
* Removes calls to mock.patch.stopall in unit tests
* Updated from global requirements
* Updated from global requirements
* Updated from global requirements
* One Convergence Neutron Plugin l3 ext support
* One Convergence Neutron Plugin Implementation
* BigSwitch: Add SSL Certificate Validation
* Updated from global requirements
* Add OpenDaylight ML2 MechanismDriver
* Implementaion of Mechanism driver for Brocade VDX cluster of switches
* Implement Mellanox ML2 MechanismDriver
* Implement OpenFlow Agent mechanism driver
* Finish off rebranding of the Nicira NVP plugin
* BigSwitch: Add agent to support neutron sec groups
* Adds the new IBM SDN-VE plugin
* Updated from global requirements
* Remove unused variable
* Change firewall to DOWN when admin state down
* Update License Headers to replace Nicira with VMware
* Developer documentation
* options: consolidate options definitions
* Rename Neutron core/service plugins for VMware NSX
* Updated from global requirements
* Sync minimum requirements
* Copy cache package from oslo-incubator
* ipt_mgr.ipv6 written in the wrong ipt_mgr.ipv4
* Validate rule uuids provided for update_policy
* Remove dependent module py3kcompat
* Add migration support from agent to NSX dhcp/metadata services
* Remove psutil dependency
* LBaaS: move agent based driver files into a separate dir
* mailmap: update .mailmap
* Return request-id in API response
* Prepare for multiple cisco ML2 mech drivers
* Support building wheels (PEP-427)
* Use oslo.rootwrap library instead of local copy
* Enables BigSwitch/Restproxy ML2 VLAN driver
* Add an explicit tox job for functional tests
* Base ML2 bulk support on the loaded drivers
* Enable hacking H233 rule
* Update RPC code from oslo
* Configure plugins by name
* Update lockutils and fixture in openstack.common
* Rename nicira configuration elements to match new naming structure
* Remove unused imports
* Rename check_nvp_config utility tool
* Corrects broken format strings in check_i18n.py
* Remove FWaaS Noop driver as default and move to unit tests dir
* Updates tox.ini to use new features
* Updated from global requirements
* Sync global requirements to pin sphinx to sphinx>=1.1.2,<1.2
* Remove start index 0 in range()
* Add fwaas_driver.ini to setup.cfg
* Add vpnaas and debug filters to setup.cfg
* Updates .gitignore
* Update Zhenguo Niu's mailmap
* Fwaas can't run in operating system without namespace feature
* Replace stubout with fixtures
* Ensure get_pid_to_kill works with rootwrap script
* Call _destroy_metadata_proxy from _destroy_router_namespaces
* Apply six for metaclass
* Updated from global requirements
* Cleanup HACKING.rst
* Fix import log_handler error with publish_errors set
* Updated from global requirements
* Utilizes assertIsNone and assertIsNotNone
* Updated from global requirements
* Fix incorrect indentations found by Pep 1.4.6+
* avoid changing the rule's own action
* Cleanup and make HACKING.rst DRYer
* Add support for managing async processes
* Remove obsolete redhat-eventlet.patch
* Open Icehouse development
* Updated from global requirements
* Fix to enable delete of firewall in PENDING_CREATE state
* Require oslo.config 1.2.0 final
* Fix FWaaS plugin to allow one firewall per tenant
* Use built-in print() instead of print statement
* FWaaS - fix reordering of rules in policy
* Support for NVP advanced FwaaS service
* FWaaS - fix policy association of firewall rule
* Add l2 population base classes
* Fix message i18n error
* Install metering_agent.ini and vpn_agent.ini
* fix conversion type missing
* vArmour gateway agent and FWaaS driver
* Enclose command args in with_venv.sh
* ML2 Mechanism Driver for Cisco Nexus
* Reference driver implementation (IPsec) for VPNaaS
* Implement ML2 port binding
* Adding more unit tests for the FWaaS agent
* Arista ML2 Mechanism driver
* ML2 Mechanism Driver for Tail-f Network Control System (NCS)
* Default to not capturing log output in tests
* Add Neutron l3 metering agent
* Update mailmap
* Fix wrong example in HACKING.rst
* Bumps hacking to 0.7.0
* remove binaries under bin
* Fixes Windows setup dependency bug
* Restore Babel to requirements.txt
* fix up inadevertant octal to make hacking pass
* Firewall as a Service (FWaaS) Iptables Driver
* Remove DHCP lease logic
* Firewall as a Service (FWaaS) Agent
* Remove last vestiges of nose
* Updated from global requirements
* Ignore pbr*.egg directory
* Fix H102, H103 Apache 2.0 license hacking check error
* Remove openstack.common.exception usage
* Adds Babel dependency missing from 555d27c
* Fix the alphabetical order in requirement files
* Followup fixes to FWaaS API patch
* Remove comments from requirements.txt (workaround pbr bug)
* Remove last of assertEquals
* Firewall as a Service (FWaaS) APIs and DB Model
* remove netifaces dependency of ryu-agent
* Add gre tunneling support for the ML2 plugin
* Add VXLAN tunneling support for the ML2 plugin
* xenapi - rename quantum to neutron
* Fix issue with pip installing oslo.config-1.2.0
* Initial Modular L2 Mechanism Driver implementation
* Add cover/ to .gitignore
* fix some missing change from quantum to neutron
* git remove old non-working packaging files
* Rename Quantum to Neutron
* Rename quantum to neutron in .gitreview
* Sync install_venv_common from oslo
* Update to use OSLO db
* Require greenlet 0.3.2 (or later)
* Remove single-version-externally-managed in setup.cfg
* Fix single-version-externally-mananged typo in setup.cfg
* Allow use of lowercase section names in conf files
* Require pbr 0.5.16 or newer
* Update to the latest stevedore
* Rename agent_loadbalancer directory to loadbalancer
* Remove unit tests that are no longer run
* Update with latest OSLO code
* Remove explicit distribute depend
* Fix and enable H90x tests
* Remove generic Exception when using assertRaises
* Add *.swo/swp to .gitignore
* python3: Introduce py33 to tox.ini
* Rename README to README.rst
* Rename requires files to standard names
* Initial Modular L2 plugin implementation
* Revert dependency on oslo.config 1.2.0
* Perform a sync with oslo-incubator
* Require oslo.config 1.2.0a2
* update mailmap
* Revert "Fix ./run_tests.sh --pep8"
* Move to pbr
* Docstrings formatted according to pep257
* relax amqplib and kombu version requirements
* Fix ./run_tests.sh --pep8
* blueprint mellanox-quantum-plugin
* Update flake8 pinned versions
* Let the cover venv run individual tests
* Copy the RHEL6 eventlet workaround from Oslo
* Remove locals() from strings substitutions
* Enable automatic validation of many HACKING rules
* Shorten the path of the nicira nvp plugin
* Allow pdb debugging in manually-invoked tests
* Reformat openstack-common.conf
* Switch to flake8 from pep8
* Parallelize quantum unit testing:
* blueprint cisco-single-config
* Add lbaas_agent files to setup.py
* Add VIRTUAL_ENV key to enviroment passed to patch_tox_env
* Pin SQLAlchemy to 0.7.x
* Sync latest Oslo components for updated copyright
* drop rfc.sh
* Replace "OpenStack LLC" with "OpenStack Foundation"
* First havana commit
* remove references to netstack in setup.py
* Switch to final 1.1.0 oslo.config release
* Update to Quantum Client 2.2.0
* Update tox.ini to support RHEL 6.x
* Switch to oslo.config
* Add common test base class to hold common things
* Pin pep8 to 1.3.3
* Add initial testr support
* LBaaS Agent Reference Implementation
* Bump python-quantumclient version to 2.1.2
* Add scheduling feature basing on agent management extension
* Remove compat cfg wrapper
* Unpin PasteDeploy dependency version
* Use testtools instead of unittest or unittest2
* Add midonet to setup.py
* Sync latest install_venv_common.py with olso
* Add check-nvp-config utility
* Add unit test for ryu-agent
* Use oslo-config-2013.1b3
* Adds Brocade Plugin implementation
* Synchronize code from oslo
* PLUMgrid quantum plugin
* Update .coveragerc
* Allow tools/install_venv_common.py to be run from within the source directory
* Updated to latest oslo-version code
* Use install_venv_common.py from oslo
* Cisco plugin cleanup
* Use babel to generate translation file
* Update WebOb version to >=1.2
* Update latest OSLO
* Adding multi switch support to the Cisco Nexus plugin
* Adds support for deploying Quantum on Windows
* Latest OSLO updates
* Port to argparse based cfg
* Add migration support to Quantum
* Undo change to require WebOb 1.2.3, instead, require only >=1.0.8
* .gitignore cleanup
* Upgrade WebOb to 1.2.3
* Logging module cleanup
* Add OVS cleanup utility
* Add tox artifacts to .gitignore
* Add restproxy.ini to config_path in setup.py
* Add script for checking i18n message
* l3 agent rpc
* Add metadata_agent.ini to config_path in setup.py
* Remove __init__.py from bin/ and tools/
* add metadata proxy support for Quantum Networks
* Use auth_token middleware in keystoneclient
* Add QUANTUM_ prefix for env used by quantum-debug
* Make tox.ini run pep8 checks on bin
* Explicitly include versioninfo in tarball
* Import lockutils and fileutils from openstack-common
* Updated openstack-common setup and version code
* Ensure that the anyjson version is correct
* Add eventlet_backdoor and threadgroup from openstack-common
* Add loopingcall from openstack-common
* Added service from openstack-common
* Drop lxml dependency
* Add uuidutils module
* Import order clean-up
* pin sqlalchemy to 0.7
* Correct Intended Audience
* Add OpenStack trove classifier for PyPI
* Improve unit test times
* l3_nat_agent was renamed to l3_agent and this was missed
* Support for several HA RabbitMQ servers
* add missing files from setup.py
* Create .mailmap file
* Lower webob dep from v1.2.0 to v1.0.8
* Implements agent for Quantum Networking testing
* Create utility to clean-up netns
* Update rootwrap; track changes in nova/cinder
* Execute unit tests for Cisco plugin with Quantum tests
* Add lease expiration script support for dnsmasq
* Add nosehtmloutput as a test dependency
* quantum l3 + floating IP support
* Updates pip requirements
* NEC OpenFlow plugin support
* remove old gflags config code
* RPC support for OVS Plugin and Agent
* Initial implemention of MetaPlugin
* RPC support for Linux Bridge Plugin and Agent
* Exempt openstack-common from pep8 check
* fix bug lp:1025526,update iniparser.py to accept empty value
* Introduce files from openstack common
* fix bug lp:1019230,update rpc from openstack-common
* implement dhcp agent for quantum
* Use setuptools git plugin for file inclusion
* Remove paste configuration details to a seperate file. blueprint use-common-cfg
* Implements the blueprint use-common-cfg for the quantum service. More specifically uses global CONF for the quantum.conf file
* Add authZ through incorporation of policy checks
* Bug #1013967 - Quantum is breaking on tests with pep 1.3
* Use openstack.common.exception
* API v2: mprove validation of post/put, rename few attributes
* Add API v2 support
* Fix up test running to match jenkins expectation
* Add build_sphinx options
* Quantum should use openstack.common.jsonutils
* Remove hardcoded version for pep8 from tools/test-requires
* Quantum should use openstack.common.importutils
* PEP8 fixes
* Bug #1002605
* Parse linuxbridge plugins using openstack.common.cfg
* Add HACKING.rst to tarball generation bug 1001220
* Include AUTHORS in release package
* Change Resource.__call__() to not leak internal errors
* Removed simplejson from pip-requires
* Remove dependency on python-quantumclient
* Add sphinx to the test build deps
* Add HACKING.rst coding style doc
* bug 963152: add a few missing files to sdist tarball
* Fix path to python-quantumclient
* Split out pip requires and aligned tox file
* Fix missing files in sdist package [bug 954906]
* Downgraded required version of WebOb to 1.0.8
* more files missing in sdist tarball
* make sure pip-requires is included in setup.py sdist
* remove pep8 and strict lxml version from setup.py
* plugin: introduce ryu plugin
* bug 934459: pip no longer supports -E
* blueprint quantum-ovs-tunnel-agent
* Initial commit: nvp plugin
* Cleanup the source distribution
* blueprint quantum-linux-bridge-plugin
* Remove quantum CLI console script
* Bug 925372: remove deprecated webob attributes (and also specify stable webob version in pip-requires)
essex-3
-------
* Make tox config work
* Pin versions to standard versions
* Split out quantum.client and quantum.common
* Quantum was missing depend on lxml
* moving batch config out of quantum-server repo
* Getting ready for the client split
* Removed erroneous print from setup.py
* Base version.py on glance
* Fix lp bug 897882
* Install a good version of pip in the venv
* Rename .quantum-venv to .venv
* Remove plugin pip-requires
essex-2
-------
* Bug #890028
* Fix for bug 900316
* Second round of packaging changes
* Changes to make pip-based tests work with jenkins
* Fix for bug 888811
* Fix for Bug #888820 - pip-requires file support for plugins
essex-1
-------
* blueprint quantum-packaging
* Add .gitreview config file for gerrit
* Add code-coverage support to run_tests.sh (lp860160)
2011.3
------
* Add rfc.sh to help with gerrit workflow
* merge tyler's unit tests for cisco plugin changes lp845140
* merge salv's no-cheetah CLI branch lp 842190
* merge sumit's branch for lp837752
* Merging latest from lp:quantum
* Merging lo:~salvatore-orlando/quantum/quantum-api-auth
* Updating CLI for not using Cheetah anymore. Now using a mechanism based on Python built-in templates
* Merging Sumit's changes including fixes for multinic support, and CLI module for working with extensions
* Merging from Cisco branch
* Merging from lp:quantum
* merge cisco consolidated plugin changes
* Merging lp:~salvatore-orlando/quantum/bug834449
* merge trunk
* Merging from lp:quantum
* merge salvatore's new cli code
* Addressing comments from Dan
* Merging from quantum
* merge cisco extensions branch
* Merging from Sumit's branch, changes to VIF-driver and Scheduler; extension action names have been changed in response to Salvatore's review comments in the extensions branch review
* Syncing with Cisco extensions branch
* Merging from Sumit's branch, import ordering related changes
* Merging the Cisco branch
* Finishing cli work Fixing bug with XML deserialization
* Merging lp:~salvatore-orlando/quantum/quantum-api-alignment
* merge latest quantum branch and resolve conflicts
* Merging lp:~asomya/quantum/lp833163 Fix for Bug #833163: Pep8 violations in recent packaging changes that were merged into trunk (Critical)
* PEP8 fixes for setup.py
* Merging lp:~cisco-openstack/quantum/802dot1qbh-vifdriver-scheduler
* Merging lp:~cisco-openstack/quantum/l2network-plugin-persistence
* Merging lp:quantum
* merging with lp:quantum
* Making Keystone version configurable
* Merging branch: lp:~danwent/quantum/test-refactor
* Syncing with lp:quantum
* Merging fixes and changes batch-config script. Thanks lp:danwent !
* Merging lp:~asomya/quantum/lp824145 Fix for Bug#824145 : Adding a setup script for quantum
* merge trunk pep8 fixes adapting CLI to API v1.0 Fixing wsgi to avoid failure with extensions
* merge trunk
* Pulling in changes from lp:quantum
* Merging Cisco's contribution to Quantum. Thanks to various folks at Cisco Systems, Quantum will have plugins to integrate with Cisco UCS blade servers using 802.1Qbh, Cisco Nexus family of switches and the ability for Quantum plugin to have multiple switches/devices within a single Quantum plugin
* Merging from Sumit's branch pylint fixes and incorporating review comments
* Mergin from cisco brach
* Merging from lp:quantum
* Introducting cheetah Updating list_nets in CLI Writing unit tests for list_nets Stubbing out with FakeConnection now
* Merging quantum extenions framework into trunk. Thanks rajaram vinkesh, deepak & santhosh for the great work!
* lp Bug#824145 : Adding a setup script for quantum
* skeleton for cli unit tests
* merge trunk
* Merged quantum trunk
* - Adding setup script
* force batch_config.py to use json, as XML has issues (see bug: 798262)
* update batch_config.py to use new client lib, hooray for deleting code
* Merging changes addressing Bug # 802772. Thanks lp:danwent !
* Merging bugfix for Bug 822890 - Added License file for Quantum code distribution
* L2 Network Plugin Framework merge
* Adding Apache Version 2.0 license file. This is the official license agreement under which Quantum code is available to the Open Source community
* merge
* merge heckj's pip-requires fixes
* updates to pip-requires for CI
* Merged quantum trunk
* Merging changes from lp:quantum
* Completing API spec alignment Unit tests aligned with changes in the API spec
* Merging the brand new Quantum-client-library feature
* Merging lp:quantum updates
* persistence of l2network & ucs plugins using mysql - db_conn.ini - configuration details of making a connection to the database - db_test_plugin.py - contains abstraction methods for storing database values in a dict and unit test cases for DB testing - l2network_db.py - db methods for l2network models - l2network_models.py - class definitions for the l2 network tables - ucs_db.py - db methods for ucs models - ucs_models.py - class definition for the ucs tables dynamic loading of the 2nd layer plugin db's based on passed arguments Create, Delete, Get, Getall, Update database methods at - Quantum, L2Network and Ucs Unit test cases for create, delete, getall and update operations for L2Network and Ucs plugins pep8 checks done branch based off revision 34 plugin-framework
* Merged from trunk
* merged the latest changes from plugin-framework branch - revision 39 conforming to the new cisco plugin directory structure and moving all db related modules into cisco/db folder updated db_test_plugin.py - added import of cisco constants module - added LOG.getLogger for logging component name - updated import module paths for l2network_models/db and ucs_models/db to use the new directory structure - updated (rearranged) imports section to obey openstack alphabetical placement convention updated db_conn.ini - updated database name from cisco_naas to quantum_l2network unit test cases ran successfully and pep8 checks done again
* merge branch for to fix bug817826
* Merging the latest changes from lp:quantum
* fix bug 817826 and similar error in batch_config.py
* merge Salvatore's api branch with fixes for tests. Tweaking branch to remove unwanted bin/quantum.py as part of merge
* Santhosh/Rajaram|latest merge from quantum and made extensions use options to load plugin
* Apply fix for bug #797419 merging lp:~salvatore-orlando/quantum/bug797419
* Merging branch lp:~netstack/quantum/quantum-unit-tests
* Merged from quantum trunk
* Adapated plugin infrastructure to allow API to pass options to plugins Now using in-memory sqlite db for tests on FakePlugin teardown() now 'resets' the in-memory db Adding unit tests for APIs
* Adding Routes>=1.12.3 to tools/pip-requires
* Merging dan wendlandt's bugfixes for Bug #800466 and improvements that enable Quantum to seamlessly run on KVM!
* more pep8 goodness
* refactor batch_config, allow multiple attaches with the empty string
* merge and pep8 cleanup
* Merging latest changes from parent repo - lp:network-service , Parent repo had approved merge proposal for merging lp:~santhom/network-service/quantum_testing_framework , which has now been merged into lp:network-service
* Merging pep8 and functional test related changes lp:~santhom/network-service/quantum_testing_framework branch
* add example to usage string for batch_config.py
* Bug fixes and clean-up, including supporting libvirt
* Santhosh/Vinkesh | Added the testing framework. Moved the smoketest to tests/functional
* Pushing initial started code based on Glance project and infrstructure work done by the melange team
* Merging in latest changes from lp:quantum
neutron-fwaas-8.0.0/PKG-INFO 0000664 0005670 0005671 00000002644 12701410073 016547 0 ustar jenkins jenkins 0000000 0000000 Metadata-Version: 1.1
Name: neutron-fwaas
Version: 8.0.0
Summary: OpenStack Networking FWaaS
Home-page: http://www.openstack.org/
Author: OpenStack
Author-email: openstack-dev@lists.openstack.org
License: UNKNOWN
Description: Welcome!
========
This package contains the code for the Neutron Firewall as a Service
(FWaaS) service. This includes third-party drivers. This package
requires Neutron to run.
External Resources:
===================
The homepage for Neutron is: http://launchpad.net/neutron. Use this
site for asking for help, and filing bugs. We use a single Launchpad
page for all Neutron projects.
Code is available on git.openstack.org at:
.
Please refer to Neutron documentation for more information:
`Neutron README.rst `_
Platform: UNKNOWN
Classifier: Environment :: OpenStack
Classifier: Intended Audience :: Information Technology
Classifier: Intended Audience :: System Administrators
Classifier: License :: OSI Approved :: Apache Software License
Classifier: Operating System :: POSIX :: Linux
Classifier: Programming Language :: Python
Classifier: Programming Language :: Python :: 2
Classifier: Programming Language :: Python :: 2.7
neutron-fwaas-8.0.0/MANIFEST.in 0000664 0005670 0005671 00000000422 12701407720 017205 0 ustar jenkins jenkins 0000000 0000000 include AUTHORS
include README.rst
include ChangeLog
include LICENSE
include neutron_fwaas/db/migration/alembic_migrations/script.py.mako
recursive-include neutron_fwaas/db/migration/alembic_migrations/versions *
exclude .gitignore
exclude .gitreview
global-exclude *.pyc
neutron-fwaas-8.0.0/tox.ini 0000664 0005670 0005671 00000007536 12701407721 017000 0 ustar jenkins jenkins 0000000 0000000 [tox]
envlist = py34,py27,pep8,pylint
minversion = 1.6
skipsdist = True
[testenv]
setenv = VIRTUAL_ENV={envdir}
usedevelop = True
install_command =
{toxinidir}/tools/tox_install.sh {env:UPPER_CONSTRAINTS_FILE:https://git.openstack.org/cgit/openstack/requirements/plain/upper-constraints.txt?h=stable/mitaka} {opts} {packages}
deps = -r{toxinidir}/requirements.txt
-r{toxinidir}/test-requirements.txt
whitelist_externals = sh
commands =
find . -type f -name "*.py[c|o]" -delete
find . -type d -name "__pycache__" -delete
sh tools/pretty_tox.sh '{posargs}'
# there is also secret magic in pretty_tox.sh which lets you run in a fail only
# mode. To do this define the TRACE_FAILONLY environmental variable.
[testenv:functional]
setenv = OS_TEST_PATH=./neutron_fwaas/tests/functional
commands =
python setup.py testr --slowest --testr-args='{posargs}'
[testenv:api]
sitepackages=True
setenv =
OS_TEST_PATH=./neutron_fwaas/tests/tempest_plugin/tests/api/
OS_TESTR_CONCURRENCY=1
TEMPEST_CONFIG_DIR={env:TEMPEST_CONFIG_DIR:/opt/stack/tempest/etc}
commands =
python setup.py testr --slowest --testr-args='{posargs}'
[testenv:scenario]
sitepackages=True
setenv =
OS_TEST_PATH=./neutron_fwaas/tests/tempest_plugin/tests/scenario/
OS_TESTR_CONCURRENCY=1
TEMPEST_CONFIG_DIR={env:TEMPEST_CONFIG_DIR:/opt/stack/tempest/etc}
commands =
python setup.py testr --slowest --testr-args='{posargs}'
[testenv:dsvm-functional]
setenv =
OS_TEST_PATH=./neutron_fwaas/tests/functional
OS_SUDO_TESTING=1
OS_ROOTWRAP_CMD=sudo {envdir}/bin/neutron-rootwrap {envdir}/etc/neutron/rootwrap.conf
OS_ROOTWRAP_DAEMON_CMD=sudo {envdir}/bin/neutron-rootwrap-daemon {envdir}/etc/neutron/rootwrap.conf
OS_FAIL_ON_MISSING_DEPS=1
whitelist_externals =
sh
cp
sudo
commands =
python setup.py testr --slowest --testr-args='{posargs}'
[testenv:releasenotes]
# TODO(ihrachys): remove once infra supports constraints for this target
install_command = {toxinidir}/tools/tox_install.sh unconstrained {opts} {packages}
commands = sphinx-build -a -E -W -d releasenotes/build/doctrees -b html releasenotes/source releasenotes/build/html
[testenv:pep8]
commands =
flake8
{toxinidir}/tools/check_unit_test_structure.sh
neutron-db-manage --subproject neutron-fwaas --database-connection sqlite:// check_migration
{[testenv:genconfig]commands}
whitelist_externals = sh
[testenv:i18n]
commands = python ./tools/check_i18n.py ./neutron_fwaas ./tools/i18n_cfg.py
[testenv:cover]
# TODO(ihrachys): remove once infra supports constraints for this target
install_command = {toxinidir}/tools/tox_install.sh unconstrained {opts} {packages}
commands =
python setup.py test --coverage --coverage-package-name=neutron_fwaas --testr-args='{posargs}'
[testenv:venv]
# TODO(ihrachys): remove once infra supports constraints for this target
install_command = {toxinidir}/tools/tox_install.sh unconstrained {opts} {packages}
commands = {posargs}
[testenv:docs]
commands = python setup.py build_sphinx
[flake8]
# E125 continuation line does not distinguish itself from next logical line
# E126 continuation line over-indented for hanging indent
# E128 continuation line under-indented for visual indent
# E129 visually indented line with same indent as next logical line
# E265 block comment should start with ‘# ‘
# H405 multi line docstring summary not separated with an empty line
# TODO(marun) H404 multi line docstring should start with a summary
ignore = E125,E126,E128,E129,E265,H404,H405
show-source = true
exclude = .venv,.git,.tox,dist,doc,*lib/python*,*egg,build,tools,.ropeproject,rally-scenarios
[testenv:pylint]
deps =
{[testenv]deps}
pylint
commands =
pylint --rcfile=.pylintrc --output-format=colorized {posargs:neutron_fwaas}
[hacking]
import_exceptions = neutron_fwaas._i18n
local-check-factory = neutron.hacking.checks.factory
[testenv:genconfig]
commands = {toxinidir}/tools/generate_config_file_samples.sh
neutron-fwaas-8.0.0/neutron_fwaas.egg-info/ 0000775 0005670 0005671 00000000000 12701410073 022011 5 ustar jenkins jenkins 0000000 0000000 neutron-fwaas-8.0.0/neutron_fwaas.egg-info/requires.txt 0000664 0005670 0005671 00000000435 12701410072 024412 0 ustar jenkins jenkins 0000000 0000000 pbr>=1.6
eventlet!=0.18.3,>=0.18.2
httplib2>=0.7.5
netaddr!=0.7.16,>=0.7.12
SQLAlchemy<1.1.0,>=1.0.10
alembic>=0.8.0
six>=1.9.0
neutron-lib>=0.0.1
oslo.config>=3.7.0
oslo.db>=4.1.0
oslo.log>=1.14.0
oslo.messaging>=4.0.0
oslo.serialization>=1.10.0
oslo.service>=1.0.0
oslo.utils>=3.5.0
neutron-fwaas-8.0.0/neutron_fwaas.egg-info/dependency_links.txt 0000664 0005670 0005671 00000000001 12701410072 026056 0 ustar jenkins jenkins 0000000 0000000
neutron-fwaas-8.0.0/neutron_fwaas.egg-info/not-zip-safe 0000664 0005670 0005671 00000000001 12701410066 024241 0 ustar jenkins jenkins 0000000 0000000
neutron-fwaas-8.0.0/neutron_fwaas.egg-info/SOURCES.txt 0000664 0005670 0005671 00000020451 12701410073 023677 0 ustar jenkins jenkins 0000000 0000000 .coveragerc
.mailmap
.pylintrc
.testr.conf
AUTHORS
CONTRIBUTING.rst
ChangeLog
HACKING.rst
LICENSE
MANIFEST.in
README.rst
TESTING.rst
babel.cfg
requirements.txt
setup.cfg
setup.py
test-requirements.txt
tox.ini
doc/source/conf.py
doc/source/index.rst
etc/README.txt
etc/oslo-config-generator/fwaas_driver.ini
neutron_fwaas/__init__.py
neutron_fwaas/_i18n.py
neutron_fwaas/opts.py
neutron_fwaas/version.py
neutron_fwaas.egg-info/PKG-INFO
neutron_fwaas.egg-info/SOURCES.txt
neutron_fwaas.egg-info/dependency_links.txt
neutron_fwaas.egg-info/entry_points.txt
neutron_fwaas.egg-info/not-zip-safe
neutron_fwaas.egg-info/pbr.json
neutron_fwaas.egg-info/requires.txt
neutron_fwaas.egg-info/top_level.txt
neutron_fwaas/common/__init__.py
neutron_fwaas/common/fwaas_constants.py
neutron_fwaas/db/__init__.py
neutron_fwaas/db/cisco/__init__.py
neutron_fwaas/db/cisco/cisco_fwaas_db.py
neutron_fwaas/db/firewall/__init__.py
neutron_fwaas/db/firewall/firewall_db.py
neutron_fwaas/db/firewall/firewall_router_insertion_db.py
neutron_fwaas/db/migration/__init__.py
neutron_fwaas/db/migration/alembic_migrations/README
neutron_fwaas/db/migration/alembic_migrations/env.py
neutron_fwaas/db/migration/alembic_migrations/script.py.mako
neutron_fwaas/db/migration/alembic_migrations/versions/4202e3047e47_add_index_tenant_id.py
neutron_fwaas/db/migration/alembic_migrations/versions/540142f314f4_fwaas_router_insertion.py
neutron_fwaas/db/migration/alembic_migrations/versions/796c68dffbb_cisco_csr_fwaas.py
neutron_fwaas/db/migration/alembic_migrations/versions/CONTRACT_HEAD
neutron_fwaas/db/migration/alembic_migrations/versions/EXPAND_HEAD
neutron_fwaas/db/migration/alembic_migrations/versions/kilo_release.py
neutron_fwaas/db/migration/alembic_migrations/versions/start_neutron_fwaas.py
neutron_fwaas/db/migration/alembic_migrations/versions/liberty/contract/67c8e8d61d5_initial.py
neutron_fwaas/db/migration/alembic_migrations/versions/liberty/expand/4b47ea298795_add_reject_rule.py
neutron_fwaas/db/migration/alembic_migrations/versions/liberty/expand/c40fbb377ad_initial.py
neutron_fwaas/db/migration/alembic_migrations/versions/mitaka/contract/458aa42b14b_fw_table_alter.py
neutron_fwaas/extensions/__init__.py
neutron_fwaas/extensions/firewall.py
neutron_fwaas/extensions/firewallrouterinsertion.py
neutron_fwaas/extensions/cisco/__init__.py
neutron_fwaas/extensions/cisco/csr_firewall_insertion.py
neutron_fwaas/services/__init__.py
neutron_fwaas/services/firewall/__init__.py
neutron_fwaas/services/firewall/fwaas_plugin.py
neutron_fwaas/services/firewall/agents/__init__.py
neutron_fwaas/services/firewall/agents/firewall_agent_api.py
neutron_fwaas/services/firewall/agents/firewall_service.py
neutron_fwaas/services/firewall/agents/l3reference/__init__.py
neutron_fwaas/services/firewall/agents/l3reference/firewall_l3_agent.py
neutron_fwaas/services/firewall/agents/varmour/__init__.py
neutron_fwaas/services/firewall/agents/varmour/varmour_api.py
neutron_fwaas/services/firewall/agents/varmour/varmour_router.py
neutron_fwaas/services/firewall/agents/varmour/varmour_utils.py
neutron_fwaas/services/firewall/agents/vyatta/__init__.py
neutron_fwaas/services/firewall/agents/vyatta/firewall_service.py
neutron_fwaas/services/firewall/agents/vyatta/fwaas_agent.py
neutron_fwaas/services/firewall/agents/vyatta/vyatta_utils.py
neutron_fwaas/services/firewall/drivers/__init__.py
neutron_fwaas/services/firewall/drivers/fwaas_base.py
neutron_fwaas/services/firewall/drivers/cisco/__init__.py
neutron_fwaas/services/firewall/drivers/cisco/csr_acl_driver.py
neutron_fwaas/services/firewall/drivers/cisco/csr_firewall_svc_helper.py
neutron_fwaas/services/firewall/drivers/linux/__init__.py
neutron_fwaas/services/firewall/drivers/linux/iptables_fwaas.py
neutron_fwaas/services/firewall/drivers/mcafee/README.rst
neutron_fwaas/services/firewall/drivers/mcafee/__init__.py
neutron_fwaas/services/firewall/drivers/mcafee/constants.py
neutron_fwaas/services/firewall/drivers/mcafee/ngfw_fwaas.py
neutron_fwaas/services/firewall/drivers/mcafee/smc_api.py
neutron_fwaas/services/firewall/drivers/varmour/__init__.py
neutron_fwaas/services/firewall/drivers/varmour/varmour_fwaas.py
neutron_fwaas/services/firewall/drivers/vyatta/README.rst
neutron_fwaas/services/firewall/drivers/vyatta/__init__.py
neutron_fwaas/services/firewall/drivers/vyatta/vyatta_fwaas.py
neutron_fwaas/services/firewall/plugins/__init__.py
neutron_fwaas/services/firewall/plugins/cisco/__init__.py
neutron_fwaas/services/firewall/plugins/cisco/cisco_fwaas_plugin.py
neutron_fwaas/tests/__init__.py
neutron_fwaas/tests/base.py
neutron_fwaas/tests/contrib/README
neutron_fwaas/tests/contrib/filters.template
neutron_fwaas/tests/contrib/gate_hook.sh
neutron_fwaas/tests/contrib/post_test_hook.sh
neutron_fwaas/tests/functional/__init__.py
neutron_fwaas/tests/functional/test_fwaas_driver.py
neutron_fwaas/tests/tempest_plugin/__init__.py
neutron_fwaas/tests/tempest_plugin/plugin.py
neutron_fwaas/tests/tempest_plugin/services/__init__.py
neutron_fwaas/tests/tempest_plugin/services/client.py
neutron_fwaas/tests/tempest_plugin/tests/__init__.py
neutron_fwaas/tests/tempest_plugin/tests/fwaas_client.py
neutron_fwaas/tests/tempest_plugin/tests/api/__init__.py
neutron_fwaas/tests/tempest_plugin/tests/api/base.py
neutron_fwaas/tests/tempest_plugin/tests/api/test_fwaas_extensions.py
neutron_fwaas/tests/tempest_plugin/tests/scenario/__init__.py
neutron_fwaas/tests/tempest_plugin/tests/scenario/base.py
neutron_fwaas/tests/tempest_plugin/tests/scenario/test_fwaas.py
neutron_fwaas/tests/unit/__init__.py
neutron_fwaas/tests/unit/db/__init__.py
neutron_fwaas/tests/unit/db/firewall/__init__.py
neutron_fwaas/tests/unit/db/firewall/test_firewall_db.py
neutron_fwaas/tests/unit/extensions/__init__.py
neutron_fwaas/tests/unit/extensions/test_firewall.py
neutron_fwaas/tests/unit/services/__init__.py
neutron_fwaas/tests/unit/services/firewall/__init__.py
neutron_fwaas/tests/unit/services/firewall/test_fwaas_plugin.py
neutron_fwaas/tests/unit/services/firewall/agents/__init__.py
neutron_fwaas/tests/unit/services/firewall/agents/test_firewall_agent_api.py
neutron_fwaas/tests/unit/services/firewall/agents/test_firewall_service.py
neutron_fwaas/tests/unit/services/firewall/agents/l3reference/__init__.py
neutron_fwaas/tests/unit/services/firewall/agents/l3reference/test_firewall_l3_agent.py
neutron_fwaas/tests/unit/services/firewall/agents/varmour/__init__.py
neutron_fwaas/tests/unit/services/firewall/agents/varmour/test_varmour_router.py
neutron_fwaas/tests/unit/services/firewall/agents/vyatta/__init__.py
neutron_fwaas/tests/unit/services/firewall/agents/vyatta/test_firewall_service.py
neutron_fwaas/tests/unit/services/firewall/agents/vyatta/test_vyatta_utils.py
neutron_fwaas/tests/unit/services/firewall/drivers/__init__.py
neutron_fwaas/tests/unit/services/firewall/drivers/cisco/__init__.py
neutron_fwaas/tests/unit/services/firewall/drivers/cisco/test_csr_acl_driver.py
neutron_fwaas/tests/unit/services/firewall/drivers/cisco/test_csr_firewall_svc_helper.py
neutron_fwaas/tests/unit/services/firewall/drivers/linux/__init__.py
neutron_fwaas/tests/unit/services/firewall/drivers/linux/test_iptables_fwaas.py
neutron_fwaas/tests/unit/services/firewall/drivers/mcafee/__init__.py
neutron_fwaas/tests/unit/services/firewall/drivers/mcafee/test_ngfw_fwaas.py
neutron_fwaas/tests/unit/services/firewall/drivers/varmour/__init__.py
neutron_fwaas/tests/unit/services/firewall/drivers/varmour/test_varmour_fwaas.py
neutron_fwaas/tests/unit/services/firewall/drivers/vyatta/__init__.py
neutron_fwaas/tests/unit/services/firewall/drivers/vyatta/test_vyatta_fwaas.py
neutron_fwaas/tests/unit/services/firewall/plugins/__init__.py
neutron_fwaas/tests/unit/services/firewall/plugins/cisco/__init__.py
neutron_fwaas/tests/unit/services/firewall/plugins/cisco/test_cisco_fwaas_plugin.py
releasenotes/notes/.placeholder
releasenotes/notes/config-file-generation-265c5256668a26bf.yaml
releasenotes/notes/enable-quotas-a3d0a21743bb1985.yaml
releasenotes/source/conf.py
releasenotes/source/index.rst
releasenotes/source/liberty.rst
releasenotes/source/unreleased.rst
releasenotes/source/_static/.placeholder
releasenotes/source/_templates/.placeholder
tools/check_i18n.py
tools/check_i18n_test_case.txt
tools/check_unit_test_structure.sh
tools/clean.sh
tools/generate_config_file_samples.sh
tools/i18n_cfg.py
tools/install_venv.py
tools/install_venv_common.py
tools/pretty_tox.sh
tools/subunit-trace.py
tools/tox_install.sh
tools/with_venv.sh neutron-fwaas-8.0.0/neutron_fwaas.egg-info/PKG-INFO 0000664 0005670 0005671 00000002644 12701410072 023113 0 ustar jenkins jenkins 0000000 0000000 Metadata-Version: 1.1
Name: neutron-fwaas
Version: 8.0.0
Summary: OpenStack Networking FWaaS
Home-page: http://www.openstack.org/
Author: OpenStack
Author-email: openstack-dev@lists.openstack.org
License: UNKNOWN
Description: Welcome!
========
This package contains the code for the Neutron Firewall as a Service
(FWaaS) service. This includes third-party drivers. This package
requires Neutron to run.
External Resources:
===================
The homepage for Neutron is: http://launchpad.net/neutron. Use this
site for asking for help, and filing bugs. We use a single Launchpad
page for all Neutron projects.
Code is available on git.openstack.org at:
.
Please refer to Neutron documentation for more information:
`Neutron README.rst `_
Platform: UNKNOWN
Classifier: Environment :: OpenStack
Classifier: Intended Audience :: Information Technology
Classifier: Intended Audience :: System Administrators
Classifier: License :: OSI Approved :: Apache Software License
Classifier: Operating System :: POSIX :: Linux
Classifier: Programming Language :: Python
Classifier: Programming Language :: Python :: 2
Classifier: Programming Language :: Python :: 2.7
neutron-fwaas-8.0.0/neutron_fwaas.egg-info/top_level.txt 0000664 0005670 0005671 00000000016 12701410072 024537 0 ustar jenkins jenkins 0000000 0000000 neutron_fwaas
neutron-fwaas-8.0.0/neutron_fwaas.egg-info/pbr.json 0000664 0005670 0005671 00000000056 12701410072 023467 0 ustar jenkins jenkins 0000000 0000000 {"git_version": "ab56228", "is_release": true} neutron-fwaas-8.0.0/neutron_fwaas.egg-info/entry_points.txt 0000664 0005670 0005671 00000001134 12701410072 025305 0 ustar jenkins jenkins 0000000 0000000 [firewall_drivers]
neutron.services.firewall.drivers.linux.iptables_fwaas.IptablesFwaasDriver = neutron_fwaas.services.firewall.drivers.linux.iptables_fwaas:IptablesFwaasDriver
neutron.services.firewall.drivers.varmour.varmour_fwaas.vArmourFwaasDriver = neutron_fwaas.services.firewall.drivers.varmour.varmour_fwaas:vArmourFwaasDriver
[neutron.db.alembic_migrations]
neutron-fwaas = neutron_fwaas.db.migration:alembic_migrations
[oslo.config.opts]
firewall.agent = neutron_fwaas.opts:list_agent_opts
[tempest.test_plugins]
neutron-fwaas = neutron_fwaas.tests.tempest_plugin.plugin:NeutronFWaaSPlugin
neutron-fwaas-8.0.0/.testr.conf 0000664 0005670 0005671 00000000372 12701407720 017541 0 ustar jenkins jenkins 0000000 0000000 [DEFAULT]
test_command=OS_STDOUT_CAPTURE=1 OS_STDERR_CAPTURE=1 OS_LOG_CAPTURE=1 ${PYTHON:-python} -m subunit.run discover -t ./ ${OS_TEST_PATH:-./neutron_fwaas/tests/unit} $LISTOPT $IDOPTION
test_id_option=--load-list $IDFILE
test_list_option=--list
neutron-fwaas-8.0.0/AUTHORS 0000664 0005670 0005671 00000020530 12701410072 016513 0 ustar jenkins jenkins 0000000 0000000 Aaron Rosen
Adam Harwell
Akash Gangil
Akihiro MOTOKI
Akihiro Motoki
Aleks Chirko
Alessandro Pilotti
Alessio Ababilov
Alessio Ababilov
Amir Sadoughi
Andre Pech
Andreas Jaeger
Andreas Jaeger
Angus Lees
Ann Kamyshnikova
Anusha Ramineni
Arvind Somy
Arvind Somya
Assaf Muller
Bertrand Lallau
Bertrand Lallau
Bhuvan Arumugam
Bob Kukura
Bob Melander
Brad Hall
Brandon Logan
Brandon Logan
Brant Knudson
Brian Haley
Brian Waldon
Carl Baldwin
Cedric Brandily
Chang Bo Guo
ChangBo Guo(gcb)
Christian Berendt
Chuck Short
Clark Boylan
Clint Byrum
Cyril Roelandt
Dan Prince
Dan Wendlandt
Davanum Srinivas
Dave Lapsley
Deepak N
Dirk Mueller
Doug Hellmann
Doug Hellmann
Doug Wiegley
Edgar Magana
Elena Ezhova
Emilien Macchi
Eugene Nikanorov
Gary Kotton
Gary Kotton
German Eichberger
Gordon Chung
Guilherme Salgado
Hareesh Puthalath
Harkirat Singh
He Jie Xu
Hemanth Ravi
Henry Gessau
Henry Gessau
HenryVIII
Hirofumi Ichihara
Hiroyuki Ito
Ignacio Scopetta
Ihar Hrachyshka
Ionuț Arțăriși
Irena Berezovsky
Isaku Yamahata
Isaku Yamahata
Itsuro Oda
JJ Asghar
Jacek Swiderski
Jakub Libosvar
James Arendt
James E. Blair
James E. Blair
Jason Kölker
Jay Pipes
Jeremy Stanley
Jiajun Liu
Joe Gordon
Joe Heck
John Dunning
Jordan Tardif
Juliano Martinez
Julien Danjou
Justin Lund
KIYOHIRO ADACHI
Keshava Bharadwaj
Kevin Benton
Kevin L. Mitchell
Koteswara Rao Kelam
Koteswara Rao Kelam
Kris Lindgren
Kun Huang
Kyle Mestery
Kyle Mestery
Li Ma
LiuNanke
Luke Gorrie
Major Hayden
Mark McClain
Mark McClain
Mark McLoughlin
Martin Hickey
Maru Newby
Maru Newby
Mate Lakat
Mathieu Rohon
Matt Riedemann
Matthew Treinish
Miguel Angel Ajo
Mohammad Banikazemi
Monty Taylor
Morgan Fainberg
Motohiro OTSUKA
Nachi Ueno
Nachi Ueno
Nader Lahouti
Nick
Numan Siddique
Oleg Bondarev
Ondřej Nový
Paddu Krishnan
Paul Michali
Paul Michali
Praneet Bachheti
Preeti Mirji
Rajaram Mallya
Rajesh Mohan
Rajesh Mohan
Ralf Haferkamp
Reedip Banerjee
Rich Curran
Roman Podoliaka
Romil Gupta
Rui Zang
Russell Bryant
Ryota MIBU
Salvatore Orlando
Salvatore Orlando
Samer Deeb
Santhosh
Santhosh Kumar
Sascha Peilicke
Sascha Peilicke
Sascha Peilicke
Sean Dague
Sean Dague
Sean M. Collins
Sean M. Collins
Sergey Lukjanov
Sergey Skripnick
Shiv Haris
Shivakumar M
Somik Behera
Somik Behera
Sridar Kandaswamy
Sukhdev
Sumit Naiksatam
Sumit Naiksatam
Sushil Kumar
Sylvain Afchain
Terry Wilson
Thierry Carrez
Thomas Bechtold
Tim Miller
Tony Breeds
Toshiaki Higuchi
Trinath Somanchi
TrinathSomanchi
Tyler Smith
Vishwanath Jayaraman
Weidong Shao
Wu Wenxiang
Xuhan Peng
YAMAMOTO Takashi
YAMAMOTO Takashi
Yaguang Tang
Yalei Wang
Yanping Qu
Yi Zhao
Ying Liu
Yong Sheng Gong
Yong Sheng Gong
Yoshihiro Kaneko
Yushiro FURUKAWA
Zang MingJie
Zhenguo Niu
ZhiQiang Fan
ZhiQiang Fan
Zhongyue Luo
alexpilotti
armando-migliaccio
armando-migliaccio
badveli_vishnuus
berlin
drzix
fujioka yuuichi
fumihiko kakuma
garyduan
gongysh
gongysh
goocher
gordon chung
justin Lund
lawrancejing
liu-sheng
liuqing
llg8212
madhusudhan-kandadai
mark mcclain
mathieu-rohon
rohitagarwalla
ronak
rossella
shihanzhang
snaiksat
sridhargaddam
sukhdev
takanorimiyagishi
trinaths
vinkesh banka
zhangguoqing
zhhuabj
neutron-fwaas-8.0.0/requirements.txt 0000664 0005670 0005671 00000001551 12701407720 020737 0 ustar jenkins jenkins 0000000 0000000 # The order of packages is significant, because pip processes them in the order
# of appearance. Changing the order has an impact on the overall integration
# process, which may cause wedges in the gate later.
pbr>=1.6 # Apache-2.0
eventlet!=0.18.3,>=0.18.2 # MIT
httplib2>=0.7.5 # MIT
netaddr!=0.7.16,>=0.7.12 # BSD
SQLAlchemy<1.1.0,>=1.0.10 # MIT
alembic>=0.8.0 # MIT
six>=1.9.0 # MIT
neutron-lib>=0.0.1 # Apache-2.0
oslo.config>=3.7.0 # Apache-2.0
oslo.db>=4.1.0 # Apache-2.0
oslo.log>=1.14.0 # Apache-2.0
oslo.messaging>=4.0.0 # Apache-2.0
oslo.serialization>=1.10.0 # Apache-2.0
oslo.service>=1.0.0 # Apache-2.0
oslo.utils>=3.5.0 # Apache-2.0
# This project does depend on neutron as a library, but the
# openstack tooling does not play nicely with projects that
# are not publicly available in pypi.
# -e git+https://git.openstack.org/openstack/neutron#egg=neutron
neutron-fwaas-8.0.0/HACKING.rst 0000664 0005670 0005671 00000000360 12701407720 017246 0 ustar jenkins jenkins 0000000 0000000 Neutron FWaaS Style Commandments
================================
Please see the Neutron HACKING.rst file for style commandments for
neutron-fwaas:
`Neutron HACKING.rst `_
neutron-fwaas-8.0.0/TESTING.rst 0000664 0005670 0005671 00000000504 12701407720 017317 0 ustar jenkins jenkins 0000000 0000000 Testing Neutron FWaaS
=====================
Please see the TESTING.rst file for the Neutron project itself. This will have
the latest up to date instructions for how to test Neutron, and will
be applicable to neutron-fwaas as well:
`Neutron TESTING.rst `_
neutron-fwaas-8.0.0/CONTRIBUTING.rst 0000664 0005670 0005671 00000000272 12701407720 020113 0 ustar jenkins jenkins 0000000 0000000 Please see the Neutron CONTRIBUTING.rst file for how to contribute to
neutron-fwaas:
`Neutron CONTRIBUTING.rst `_
neutron-fwaas-8.0.0/releasenotes/ 0000775 0005670 0005671 00000000000 12701410073 020135 5 ustar jenkins jenkins 0000000 0000000 neutron-fwaas-8.0.0/releasenotes/notes/ 0000775 0005670 0005671 00000000000 12701410073 021265 5 ustar jenkins jenkins 0000000 0000000 neutron-fwaas-8.0.0/releasenotes/notes/config-file-generation-265c5256668a26bf.yaml 0000664 0005670 0005671 00000000435 12701407720 030557 0 ustar jenkins jenkins 0000000 0000000 ---
prelude: >
Generation of sample Neutron FWaaS configuration files.
features:
- Neutron FWaaS no longer includes static example configuration files.
Instead, use tools/generate_config_file_samples.sh to generate them.
The files are generated with a .sample extension.
neutron-fwaas-8.0.0/releasenotes/notes/.placeholder 0000664 0005670 0005671 00000000000 12701407720 023543 0 ustar jenkins jenkins 0000000 0000000 neutron-fwaas-8.0.0/releasenotes/notes/enable-quotas-a3d0a21743bb1985.yaml 0000664 0005670 0005671 00000001352 12701407720 027041 0 ustar jenkins jenkins 0000000 0000000 ---
prelude: >
Enable quotas for FWaaS.
features:
- The FWaaS extension will register quotas.
The default values for quota_firewall and
quota_firewall_policy are set to 10.
The default value for quota_firewall_rule
is set to 100.
Quotas can be adjusted in the conf files, including
-1 values to allow unlimited.
issues:
- Tenants may receive a 409 Conflict error with a
message body containing a quota exceeded message
during resource creation if their quota is exceeded.
other:
- Operators that increase the default limit for quota_routers
from 10 may want to bump FWaaS quotas as well, since with
router insertion a tenant can potentially have a unique
policy and firewall for each router.
neutron-fwaas-8.0.0/releasenotes/source/ 0000775 0005670 0005671 00000000000 12701410073 021435 5 ustar jenkins jenkins 0000000 0000000 neutron-fwaas-8.0.0/releasenotes/source/index.rst 0000664 0005670 0005671 00000000221 12701407721 023277 0 ustar jenkins jenkins 0000000 0000000 =============================
Neutron FWaaS Release Notes
=============================
.. toctree::
:maxdepth: 1
liberty
unreleased
neutron-fwaas-8.0.0/releasenotes/source/_templates/ 0000775 0005670 0005671 00000000000 12701410073 023572 5 ustar jenkins jenkins 0000000 0000000 neutron-fwaas-8.0.0/releasenotes/source/_templates/.placeholder 0000664 0005670 0005671 00000000000 12701407720 026050 0 ustar jenkins jenkins 0000000 0000000 neutron-fwaas-8.0.0/releasenotes/source/unreleased.rst 0000664 0005670 0005671 00000000160 12701407720 024320 0 ustar jenkins jenkins 0000000 0000000 ==============================
Current Series Release Notes
==============================
.. release-notes::
neutron-fwaas-8.0.0/releasenotes/source/liberty.rst 0000664 0005670 0005671 00000000222 12701407720 023642 0 ustar jenkins jenkins 0000000 0000000 ==============================
Liberty Series Release Notes
==============================
.. release-notes::
:branch: origin/stable/liberty
neutron-fwaas-8.0.0/releasenotes/source/conf.py 0000664 0005670 0005671 00000021773 12701407720 022753 0 ustar jenkins jenkins 0000000 0000000 # -*- coding: utf-8 -*-
# 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.
# Neutron FWaaS Release Notes documentation build configuration file, created
# by # sphinx-quickstart on Tue Nov 3 17:40:50 2015.
#
# This file is execfile()d with the current directory set to its
# containing dir.
#
# Note that not all possible configuration values are present in this
# autogenerated file.
#
# All configuration values have a default; values that are commented out
# serve to show the default.
# If extensions (or modules to document with autodoc) are in another directory,
# add these directories to sys.path here. If the directory is relative to the
# documentation root, use os.path.abspath to make it absolute, like shown here.
# sys.path.insert(0, os.path.abspath('.'))
# -- General configuration ------------------------------------------------
# If your documentation needs a minimal Sphinx version, state it here.
# needs_sphinx = '1.0'
# Add any Sphinx extension module names here, as strings. They can be
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
# ones.
extensions = [
'oslosphinx',
'reno.sphinxext',
]
# Add any paths that contain templates here, relative to this directory.
templates_path = ['_templates']
# The suffix of source filenames.
source_suffix = '.rst'
# The encoding of source files.
# source_encoding = 'utf-8-sig'
# The master toctree document.
master_doc = 'index'
# General information about the project.
project = u'Neutron FWaaS Release Notes'
copyright = u'2015, Neutron FWaaS Developers'
# The version info for the project you're documenting, acts as replacement for
# |version| and |release|, also used in various other places throughout the
# built documents.
#
# The short X.Y version.
from neutron_fwaas.version import version_info as neutron_fwaas_version
# The full version, including alpha/beta/rc tags.
release = neutron_fwaas_version.version_string_with_vcs()
# The short X.Y version.
version = neutron_fwaas_version.canonical_version_string()
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
# language = None
# There are two options for replacing |today|: either, you set today to some
# non-false value, then it is used:
# today = ''
# Else, today_fmt is used as the format for a strftime call.
# today_fmt = '%B %d, %Y'
# List of patterns, relative to source directory, that match files and
# directories to ignore when looking for source files.
exclude_patterns = []
# The reST default role (used for this markup: `text`) to use for all
# documents.
# default_role = None
# If true, '()' will be appended to :func: etc. cross-reference text.
# add_function_parentheses = True
# If true, the current module name will be prepended to all description
# unit titles (such as .. function::).
# add_module_names = True
# If true, sectionauthor and moduleauthor directives will be shown in the
# output. They are ignored by default.
# show_authors = False
# The name of the Pygments (syntax highlighting) style to use.
pygments_style = 'sphinx'
# A list of ignored prefixes for module index sorting.
# modindex_common_prefix = []
# If true, keep warnings as "system message" paragraphs in the built documents.
# keep_warnings = False
# -- Options for HTML output ----------------------------------------------
# The theme to use for HTML and HTML Help pages. See the documentation for
# a list of builtin themes.
html_theme = 'default'
# Theme options are theme-specific and customize the look and feel of a theme
# further. For a list of options available for each theme, see the
# documentation.
# html_theme_options = {}
# Add any paths that contain custom themes here, relative to this directory.
# html_theme_path = []
# The name for this set of Sphinx documents. If None, it defaults to
# " v documentation".
# html_title = None
# A shorter title for the navigation bar. Default is the same as html_title.
# html_short_title = None
# The name of an image file (relative to this directory) to place at the top
# of the sidebar.
# html_logo = None
# The name of an image file (within the static path) to use as favicon of the
# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
# pixels large.
# html_favicon = None
# Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files,
# so a file named "default.css" will overwrite the builtin "default.css".
html_static_path = ['_static']
# Add any extra paths that contain custom files (such as robots.txt or
# .htaccess) here, relative to this directory. These files are copied
# directly to the root of the documentation.
# html_extra_path = []
# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
# using the given strftime format.
# html_last_updated_fmt = '%b %d, %Y'
# If true, SmartyPants will be used to convert quotes and dashes to
# typographically correct entities.
# html_use_smartypants = True
# Custom sidebar templates, maps document names to template names.
# html_sidebars = {}
# Additional templates that should be rendered to pages, maps page names to
# template names.
# html_additional_pages = {}
# If false, no module index is generated.
# html_domain_indices = True
# If false, no index is generated.
# html_use_index = True
# If true, the index is split into individual pages for each letter.
# html_split_index = False
# If true, links to the reST sources are added to the pages.
# html_show_sourcelink = True
# If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
# html_show_sphinx = True
# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
# html_show_copyright = True
# If true, an OpenSearch description file will be output, and all pages will
# contain a tag referring to it. The value of this option must be the
# base URL from which the finished HTML is served.
# html_use_opensearch = ''
# This is the file name suffix for HTML files (e.g. ".xhtml").
# html_file_suffix = None
# Output file base name for HTML help builder.
htmlhelp_basename = 'NeutronFWaaSReleaseNotesdoc'
# -- Options for LaTeX output ---------------------------------------------
latex_elements = {
# The paper size ('letterpaper' or 'a4paper').
# 'papersize': 'letterpaper',
# The font size ('10pt', '11pt' or '12pt').
# 'pointsize': '10pt',
# Additional stuff for the LaTeX preamble.
# 'preamble': '',
}
# Grouping the document tree into LaTeX files. List of tuples
# (source start file, target name, title,
# author, documentclass [howto, manual, or own class]).
latex_documents = [
('index', 'NeutronFWaaSReleaseNotes.tex',
u'Neutron FWaaS Release Notes Documentation',
u'Neutron FWaaS Developers', 'manual'),
]
# The name of an image file (relative to this directory) to place at the top of
# the title page.
# latex_logo = None
# For "manual" documents, if this is true, then toplevel headings are parts,
# not chapters.
# latex_use_parts = False
# If true, show page references after internal links.
# latex_show_pagerefs = False
# If true, show URL addresses after external links.
# latex_show_urls = False
# Documents to append as an appendix to all manuals.
# latex_appendices = []
# If false, no module index is generated.
# latex_domain_indices = True
# -- Options for manual page output ---------------------------------------
# One entry per manual page. List of tuples
# (source start file, name, description, authors, manual section).
man_pages = [
('index', 'neutronfwaasreleasenotes', u'Neutron FWaaS Release Notes '
'Documentation', [u'Neutron FWaaS Developers'], 1)
]
# If true, show URL addresses after external links.
# man_show_urls = False
# -- Options for Texinfo output -------------------------------------------
# Grouping the document tree into Texinfo files. List of tuples
# (source start file, target name, title, author,
# dir menu entry, description, category)
texinfo_documents = [
('index', 'NeutronFWaaSReleaseNotes', u'Neutron FWaaS Release Notes '
'Documentation',
u'Neutron FWaaS Developers', 'NeutronFWaaSReleaseNotes',
'One line description of project.',
'Miscellaneous'),
]
# Documents to append as an appendix to all manuals.
# texinfo_appendices = []
# If false, no module index is generated.
# texinfo_domain_indices = True
# How to display URL addresses: 'footnote', 'no', or 'inline'.
# texinfo_show_urls = 'footnote'
# If true, do not generate a @detailmenu in the "Top" node's menu.
# texinfo_no_detailmenu = False
neutron-fwaas-8.0.0/releasenotes/source/_static/ 0000775 0005670 0005671 00000000000 12701410073 023063 5 ustar jenkins jenkins 0000000 0000000 neutron-fwaas-8.0.0/releasenotes/source/_static/.placeholder 0000664 0005670 0005671 00000000000 12701407720 025341 0 ustar jenkins jenkins 0000000 0000000 neutron-fwaas-8.0.0/README.rst 0000664 0005670 0005671 00000001177 12701407720 017146 0 ustar jenkins jenkins 0000000 0000000 Welcome!
========
This package contains the code for the Neutron Firewall as a Service
(FWaaS) service. This includes third-party drivers. This package
requires Neutron to run.
External Resources:
===================
The homepage for Neutron is: http://launchpad.net/neutron. Use this
site for asking for help, and filing bugs. We use a single Launchpad
page for all Neutron projects.
Code is available on git.openstack.org at:
.
Please refer to Neutron documentation for more information:
`Neutron README.rst `_
neutron-fwaas-8.0.0/.mailmap 0000664 0005670 0005671 00000001116 12701407720 017071 0 ustar jenkins jenkins 0000000 0000000 # Format is:
#
#