def calculate(context, operation, object_type, object_uuid, data):
    """Calculate resource deps in journaled operations.

    As a rule of thumb validation takes into consideration only operations in
    pending or processing state, other states are irrelevant.
    :param context: enginefacade context
    :param row: entry in journal entry to be validated
    """
    deps = []
    if operation == odl_const.ODL_DELETE:
        return _get_delete_dependencies(context, object_type, object_uuid)
    elif operation == odl_const.ODL_UPDATE:
        deps.extend(
            db.get_pending_or_processing_ops(
                context, object_uuid,
                operation=(odl_const.ODL_CREATE, odl_const.ODL_UPDATE)))
    elif operation != odl_const.ODL_CREATE:
        raise ValueError(_("unsupported operation {}").format(operation))

    # Validate deps if there are any to validate.
    dep_generator = _CREATE_OR_UPDATE_DEP_GENERATOR.get(object_type)
    if dep_generator is not None:
        object_ids = dep_generator(data)
        if object_ids is not None:
            deps.extend(_get_older_operations(context, object_ids))

    return deps
def _vif_type_from_conf(conf, userspace_datapath_types):

    # take vif_type from datapath_type ------------------------------------
    if conf.datapath_type:
        # take it from  datapath_type
        if conf.datapath_type in USERSPACE_DATAPATH_TYPES:
            if conf.datapath_type not in userspace_datapath_types:
                LOG.warning(
                    "Using user space data path type '%s' even if no "
                    "support was detected.", conf.datapath_type)
            return 'vhostuser'
        else:
            return 'ovs'

    # take vif_type from ovs_dpdk -----------------------------------------
    if conf.ovs_dpdk is True:
        if userspace_datapath_types:
            return 'vhostuser'

        raise ValueError(_(
            "--ovs_dpdk option was specified but the 'netdev' datapath_type "
            "was not enabled. "
            "To override use option --datapath_type=netdev"))

    elif conf.ovs_dpdk is False:
        return 'ovs'

    # take detected dtype -------------------------------------------------
    if userspace_datapath_types:
        return 'vhostuser'

    return 'ovs'
Example #3
0
    def start(self):
        if self._running:
            raise RuntimeError(
                _("Thread has to be stopped before started again")
            )

        super(JournalPeriodicProcessor, self).start()
        LOG.debug('JournalPeriodicProcessor starting')
        self._journal.start()
        self._timer = loopingcall.FixedIntervalLoopingCall(self._call_journal)
        self._timer.start(self._interval)
        self._start_maintenance_task()
        self._create_pidfile()
        self._running = True
    def post(cls, resource_type, resource_dict, urlpath, resource_list):
        """No ID in URL, elements in resource_list must have ID"""

        if resource_list is None:
            raise ValueError(_("resource_list can not be None"))

        for resource in resource_list:
            if resource['id'] in resource_dict:
                LOG.debug("%s %s already exists", resource_type,
                          resource['id'])
                response = cls._make_response(NOT_ALLOWED)
                raise requests.exceptions.HTTPError(response=response)

            resource_dict[resource['id']] = deepcopy(resource)

        return cls._make_response(NO_CONTENT)
    def put(cls, resource_type, resource_dict, urlpath, resource_list):

        resource_id = cls._get_resource_id(urlpath)

        if resource_list is None:
            raise ValueError(_("resource_list can not be None"))

        if resource_id and len(resource_list) != 1:
            LOG.debug("Updating %s with multiple resources", urlpath)
            response = cls._make_response(BAD_REQUEST)
            raise requests.exceptions.HTTPError(response=response)

        for resource in resource_list:
            res_id = resource_id or resource['id']
            if res_id in resource_dict:
                resource_dict[res_id].update(deepcopy(resource))
            else:
                LOG.debug("%s %s does not exist", resource_type, res_id)
                response = cls._make_response(NOT_FOUND)
                raise requests.exceptions.HTTPError(response=response)

        return cls._make_response(NO_CONTENT)
    def odl_create_websocket(cls, odl_url, path, datastore, scope,
                             packet_handler, status_cb=None,
                             leaf_node_only=False):
        """Create a websocket connection with ODL.

                This method will create a websocket client based on path,
                datastore and scope params. On data recv from websocket
                packet_handler callback is called. status_cb callback can be
                provided if notifications are requried for socket status
                changes
        """

        if odl_url is None:
            LOG.error("invalid odl url", exc_info=True)
            raise ValueError(_("Invalid ODL URL"))

        odl_rest_client = odl_client.OpenDaylightRestClient.create_client(
            odl_url)
        return cls(
            odl_rest_client, path, datastore, scope, leaf_node_only,
            packet_handler, cfg.CONF.ml2_odl.timeout, status_cb
        )
def _vif_details_from_conf(conf, uuid, vif_type):
    host_addresses = [conf.local_ip or conf.host]
    if vif_type == 'ovs':
        # OVS legacy mode
        return {"uuid": uuid,
                "host_addresses": host_addresses,
                "has_datapath_type_netdev": False,
                "support_vhost_user": False}

    elif vif_type == 'vhostuser':
        # enable VHOSTUSER
        return {"uuid": uuid,
                "host_addresses": host_addresses,
                "has_datapath_type_netdev": True,
                "support_vhost_user": True,
                "port_prefix": conf.vhostuser_port_prefix,
                "vhostuser_socket_dir": conf.vhostuser_socket_dir,
                "vhostuser_ovs_plug": conf.vhostuser_ovs_plug,
                "vhostuser_mode": conf.vhostuser_mode,
                "vhostuser_socket": os.path.join(
                    conf.vhostuser_socket_dir,
                    conf.vhostuser_port_prefix + '$PORT_ID')}
    raise ValueError(_("vif type: '%s' not supported") % vif_type)
Example #8
0
#         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_config import cfg

from networking_odl._i18n import _


odl_opts = [
    cfg.StrOpt('url',
               help=_("HTTP URL of OpenDaylight REST interface.")),
    cfg.StrOpt('username',
               help=_("HTTP username for authentication.")),
    cfg.StrOpt('password', secret=True,
               help=_("HTTP password for authentication.")),
    cfg.IntOpt('timeout', default=10,
               help=_("HTTP timeout in seconds.")),
    cfg.IntOpt('session_timeout', default=30,
               help=_("Tomcat session timeout in minutes.")),
    cfg.IntOpt('sync_timeout', default=10,
               help=_("(V2 driver) Sync thread timeout in seconds.")),
    cfg.IntOpt('retry_count', default=5,
               help=_("(V2 driver) Number of times to retry a row "
                      "before failing.")),
    cfg.IntOpt('maintenance_interval', default=300,
               help=_("(V2 driver) Journal maintenance operations interval "
    def _subscribe_websocket(self):
        """ODL Websocket change notification subscription"""
        # Check ODL URL for details on this process
        # https://wiki.opendaylight.org/view/OpenDaylight_Controller:MD-SAL:Restconf:Change_event_notification_subscription#rpc_create-data-change-event-subscription # noqa: E501 # pylint: disable=line-too-long

        # Invoke rpc create-data-change-event-subscription
        ws_create_dce_subs_url = ("restconf/operations/sal-remote:"
                                  "create-data-change-event-subscription")
        odl_subscription_data = {
            'input': {
                'path': self.path,
                'sal-remote-augment:datastore': self.datastore,
                'sal-remote-augment:scope': self.scope,
                'sal-remote-augment:notification-output-type': 'JSON'
            }
        }
        try:
            response = self.odl_rest_client.sendjson('post',
                                                     ws_create_dce_subs_url,
                                                     odl_subscription_data)
            response.raise_for_status()
        except exceptions.ConnectionError:
            LOG.error("cannot connect to the opendaylight controller")
            return None
        except exceptions.HTTPError as e:
            # restconf returns 400 on operation when path is not available
            if e.response.status_code == codes.bad_request:
                LOG.debug("response code bad_request (400)"
                          "check path for websocket connection")
                raise ValueError(_("bad_request (http400),check path."))
            else:
                LOG.warning("websocket connection failed", exc_info=True)
                return None
        except Exception:
            LOG.error("websocket subscription failed", exc_info=True)
            return None

        # Subscribing to stream. Returns websocket URL to listen to
        ws_dce_subs_url = """restconf/streams/stream/"""
        try:
            stream_name = response.json()
            stream_name = stream_name['output']['stream-name']
            url = ws_dce_subs_url + stream_name
            if self.leaf_node_only:
                url += "?odl-leaf-nodes-only=true"
            response = self.odl_rest_client.get(url)
            response.raise_for_status()
            stream_url = response.headers['location']
            LOG.debug("websocket stream URL: %s", stream_url)
            return stream_url
        except exceptions.ConnectionError:
            LOG.error("cannot connect to the opendaylight controller")
            return None
        except exceptions.HTTPError as e:
            # restconf returns 404 on operation when there is no entry
            if e.response.status_code == codes.not_found:
                LOG.debug("response code not_found (404)"
                          "unable to websocket connection url")
                raise ValueError(_("bad_request (http400),check path"))
            else:
                LOG.warning("websocket connection failed")
                return None
        except ValueError:
            with excutils.save_and_reraise_exception():
                LOG.error("websocket subscribe got invalid stream name")
        except KeyError:
            LOG.error("websocket subscribe got bad stream data")
            raise ValueError(_("websocket subscribe bad stream data"))
        except Exception:
            LOG.error("websocket subscription failed", exc_info=True)
            return None
Example #10
0
#    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_config import cfg

from networking_odl._i18n import _

odl_opts = [
    cfg.StrOpt('url', help=_("HTTP URL of OpenDaylight REST interface.")),
    cfg.StrOpt('username', help=_("HTTP username for authentication.")),
    cfg.StrOpt('password',
               secret=True,
               help=_("HTTP password for authentication.")),
    cfg.IntOpt('timeout', default=10, help=_("HTTP timeout in seconds.")),
    cfg.IntOpt('session_timeout',
               default=30,
               help=_("Tomcat session timeout in minutes.")),
    cfg.IntOpt('sync_timeout',
               default=10,
               help=_("(V2 driver) Sync thread timeout in seconds.")),
    cfg.IntOpt('retry_count',
               default=5,
               help=_("(V2 driver) Number of times to retry a row "
                      "before failing.")),
Example #11
0
#         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_config import cfg

from networking_odl._i18n import _


odl_opts = [
    cfg.StrOpt('url',
               help=_("HTTP URL of OpenDaylight REST interface.")),
    cfg.StrOpt('username',
               help=_("HTTP username for authentication.")),
    cfg.StrOpt('password', secret=True,
               help=_("HTTP password for authentication.")),
    cfg.IntOpt('timeout', default=10,
               help=_("HTTP timeout in seconds.")),
    cfg.IntOpt('session_timeout', default=30,
               help=_("Tomcat session timeout in minutes.")),
    cfg.IntOpt('sync_timeout', default=10,
               help=_("(V2 driver) Sync thread timeout in seconds.")),
    cfg.IntOpt('retry_count', default=5,
               help=_("(V2 driver) Number of times to retry a row "
                      "before failing.")),
    cfg.IntOpt('maintenance_interval', default=300,
               help=_("(V2 driver) Journal maintenance operations interval "
Example #12
0
#         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_config import cfg

from networking_odl._i18n import _


odl_opts = [
    cfg.StrOpt('url',
               help=_("HTTP URL of OpenDaylight REST interface.")),
    cfg.StrOpt('username',
               help=_("HTTP username for authentication")),
    cfg.StrOpt('password', secret=True,
               help=_("HTTP password for authentication")),
    cfg.IntOpt('timeout', default=10,
               help=_("HTTP timeout in seconds.")),
    cfg.IntOpt('session_timeout', default=30,
               help=_("Tomcat session timeout in minutes.")),
    cfg.IntOpt('sync_timeout', default=10,
               help=_("(V2 driver) Sync thread timeout in seconds.")),
    cfg.IntOpt('retry_count', default=5,
               help=_("(V2 driver) Number of times to retry a row "
                      "before failing.")),
    cfg.BoolOpt('enable_lightweight_testing',
                default=False,
from networking_odl._i18n import _


LOG = logging.getLogger(__name__)

USERSPACE_DATAPATH_TYPES = ['netdev', 'dpdkvhostuser']

COMMAND_LINE_OPTIONS = [

    cfg.ListOpt(
        'allowed_network_types',
        default=['local', 'flat', 'vlan', 'vxlan', 'gre'],
        help=_("""
            Specifies allowed network types given as a Comma-separated list of
            types.

            Default: --allowed_network_types=local,vlan,vxlan,gre
            """)),

    cfg.DictOpt(
        'bridge_mappings',
        default={},
        help=_("""
            Comma-separated list of <physical_network>:<bridge> tuples mapping
            physical network names to the agent's node-specific Open vSwitch
            bridge names to be used for flat and VLAN networks. The length of
            bridge names should be no more than 11. Each bridge must exist, and
            should have a physical network interface configured as a port. All
            physical networks configured on the server should have mappings to
            appropriate bridges on each agent.
#    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_config import cfg

from networking_odl._i18n import _

odl_opts = [
    cfg.StrOpt('url', help=_("HTTP URL of OpenDaylight REST interface.")),
    cfg.StrOpt('username', help=_("HTTP username for authentication.")),
    cfg.StrOpt('password',
               secret=True,
               help=_("HTTP password for authentication.")),
    cfg.IntOpt('timeout', default=10, help=_("HTTP timeout in seconds.")),
    cfg.IntOpt('session_timeout',
               default=30,
               help=_("Tomcat session timeout in minutes.")),
    cfg.IntOpt('sync_timeout',
               default=10,
               help=_("(V2 driver) Sync thread timeout in seconds.")),
    cfg.IntOpt('retry_count',
               default=5,
               help=_("(V2 driver) Number of times to retry a row "
                      "before failing.")),
Example #15
0
    def sync_from_callback_precommit(self, context, operation, res_type,
                                     res_id, resource_dict, **kwargs):
        object_type = res_type.singular
        if resource_dict is not None:
            resource_dict = resource_dict[object_type]

        if (operation == odl_const.ODL_CREATE
                and object_type == odl_const.ODL_SG):
            self._sync_security_group_create_precommit(context, operation,
                                                       object_type, res_id,
                                                       resource_dict)
            return

        # NOTE(yamahata): in security group/security gorup rule case,
        # orm object is passed. not resource dict. So we have to convert it
        # into resource_dict
        if not isinstance(resource_dict, dict) and resource_dict is not None:
            if object_type == odl_const.ODL_SG:
                resource_dict = self._make_security_group_dict(resource_dict)
            elif object_type == odl_const.ODL_SG_RULE:
                resource_dict = self._make_security_group_rule_dict(
                    resource_dict)
        # NOTE(yamahata): bug work around
        # callback for update of security grouop doesn't pass complete
        # info. So we have to build it. Once the bug is fixed, remove
        # this bug work around.
        # https://launchpad.net/bugs/1546910
        # https://review.openstack.org/#/c/281693/
        elif (object_type == odl_const.ODL_SG
              and operation == odl_const.ODL_UPDATE):
            # NOTE(yamahata): precommit_update is called before updating
            # values. so context.session.{new, dirty} doesn't include sg
            # in question. a dictionary with new values needs to be build.
            core_plugin = directory.get_plugin()
            sg = core_plugin._get_security_group(context, res_id)
            tmp_dict = self._make_security_group_dict(sg)
            tmp_dict.update(resource_dict)
            resource_dict = tmp_dict

        object_uuid = (resource_dict.get('id')
                       if operation == 'create' else res_id)
        if object_uuid is None:
            # NOTE(yamahata): bug work around bug/1546910
            # TODO(yamahata): once the following patch is merged
            # remove this bug work around
            # https://review.openstack.org/#/c/281693/
            assert object_type == odl_const.ODL_SG_RULE
            # NOTE(yamahata): bulk creation case
            # context.session.new accumulates all newly created orm object.
            # there is no easy way to pick up the lastly added orm object.
            rules = [
                rule for rule in context.session.new
                if (isinstance(rule, securitygroup.SecurityGroupRule))
            ]
            if len(rules) == 1:
                object_uuid = rules[0].id
                resource_dict['id'] = object_uuid
            else:
                LOG.error(_LE("bulk creation of sgrule isn't supported"))
                raise NotImplementedError(
                    _("unsupporetd bulk creation of security group rule"))
        journal.record(context, object_type, object_uuid, operation,
                       resource_dict)
        # NOTE(yamahata): DB auto deletion
        # Security Group Rule under this Security Group needs to
        # be deleted. At NeutronDB layer rules are auto deleted with
        # cascade='all,delete'.
        if (object_type == odl_const.ODL_SG
                and operation == odl_const.ODL_DELETE):
            for rule in kwargs['security_group'].rules:
                journal.record(context, odl_const.ODL_SG_RULE, rule.id,
                               odl_const.ODL_DELETE, [object_uuid])
    def _subscribe_websocket(self):
        """ODL Websocket change notification subscription"""
        # Check ODL URL for details on this process
        # https://wiki.opendaylight.org/view/OpenDaylight_Controller:MD-SAL:Restconf:Change_event_notification_subscription#rpc_create-data-change-event-subscription # noqa: E501 # pylint: disable=line-too-long

        # Invoke rpc create-data-change-event-subscription
        ws_create_dce_subs_url = ("restconf/operations/sal-remote:"
                                  "create-data-change-event-subscription")
        odl_subscription_data = {'input': {
            'path': self.path,
            'sal-remote-augment:datastore': self.datastore,
            'sal-remote-augment:scope': self.scope,
            'sal-remote-augment:notification-output-type': 'JSON'
        }}
        try:
            response = self.odl_rest_client.sendjson('post',
                                                     ws_create_dce_subs_url,
                                                     odl_subscription_data)
            response.raise_for_status()
        except exceptions.ConnectionError:
            LOG.error("cannot connect to the opendaylight controller")
            return None
        except exceptions.HTTPError as e:
            # restconf returns 400 on operation when path is not available
            if e.response.status_code == codes.bad_request:
                LOG.debug("response code bad_request (400)"
                          "check path for websocket connection")
                raise ValueError(_("bad_request (http400),check path."))
            else:
                LOG.warning("websocket connection failed",
                            exc_info=True)
                return None
        except Exception:
            LOG.error("websocket subscription failed", exc_info=True)
            return None

        # Subscribing to stream. Returns websocket URL to listen to
        ws_dce_subs_url = """restconf/streams/stream/"""
        try:
            stream_name = response.json()
            stream_name = stream_name['output']['stream-name']
            url = ws_dce_subs_url + stream_name
            if self.leaf_node_only:
                url += "?odl-leaf-nodes-only=true"
            response = self.odl_rest_client.get(url)
            response.raise_for_status()
            stream_url = response.headers['location']
            LOG.debug("websocket stream URL: %s", stream_url)
            return stream_url
        except exceptions.ConnectionError:
            LOG.error("cannot connect to the opendaylight controller")
            return None
        except exceptions.HTTPError as e:
            # restconf returns 404 on operation when there is no entry
            if e.response.status_code == codes.not_found:
                LOG.debug("response code not_found (404)"
                          "unable to websocket connection url")
                raise ValueError(_("bad_request (http400),check path"))
            else:
                LOG.warning("websocket connection failed")
                return None
        except ValueError:
            with excutils.save_and_reraise_exception():
                LOG.error("websocket subscribe got invalid stream name")
        except KeyError:
            LOG.error("websocket subscribe got bad stream data")
            raise ValueError(_("websocket subscribe bad stream data"))
        except Exception:
            LOG.error("websocket subscription failed", exc_info=True)
            return None
"""

import collections
import re
import sys

import six

from oslo_config import cfg

from networking_odl._i18n import _
from networking_odl.journal import journal

COMMAND_LINE_OPTIONS = [
    cfg.StrOpt('file', default=None,
               help=_("Log file to analyze.")),
    cfg.IntOpt('slowest', min=1, default=10,
               help=_("Prints the N slowest entries (10 by default).")),
]

# This regex will match any replacement key in the log message and extract
# the key name.
KEY_MATCHER = re.compile(r'\%\((\S+)\)s')
LOG_KEYS = KEY_MATCHER.findall(journal.LOG_ENTRY_TEMPLATE)
KEY_TEMP_PATTERN = 'KEYPATTERN'
LOG_MATCHER = re.compile(
    re.sub(KEY_TEMP_PATTERN, r'(\S+)', re.escape(
        KEY_MATCHER.sub(KEY_TEMP_PATTERN, journal.LOG_ENTRY_TEMPLATE))))
ENTRY_LOG_TEMPLATE = ' * Entry id: %s, processing time: %.3fs; %s %s %s'

EntryStats = collections.namedtuple(
from networking_odl._i18n import _
from networking_odl._i18n import _LE
from networking_odl._i18n import _LI
from networking_odl._i18n import _LW

LOG = log.getLogger(__name__)

USERSPACE_DATAPATH_TYPES = ['netdev', 'dpdkvhostuser']

COMMAND_LINE_OPTIONS = [
    cfg.ListOpt('allowed_network_types',
                default=['local', 'vlan', 'vxlan', 'gre'],
                help=_("""
            Specifies allowed network types given as a Comma-separated list of
            types.

            Default: --allowed_network_types=local,vlan,vxlan,gre
            """)),
    cfg.DictOpt('bridge_mappings',
                default={},
                help=_("""
            Comma-separated list of <physical_network>:<bridge> tuples mapping
            physical network names to the agent's node-specific Open vSwitch
            bridge names to be used for flat and VLAN networks. The length of
            bridge names should be no more than 11. Each bridge must exist, and
            should have a physical network interface configured as a port. All
            physical networks configured on the server should have mappings to
            appropriate bridges on each agent.

            Note: If you remove a bridge from this mapping, make sure to
            disconnect it from the integration bridge as it won't be managed by
Example #19
0
#    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_config import cfg

from networking_odl._i18n import _

odl_opts = [
    cfg.StrOpt('url', help=_("HTTP URL of OpenDaylight REST interface.")),
    cfg.StrOpt('username', help=_("HTTP username for authentication.")),
    cfg.StrOpt('password',
               secret=True,
               help=_("HTTP password for authentication.")),
    cfg.IntOpt('timeout', default=10, help=_("HTTP timeout in seconds.")),
    cfg.IntOpt('session_timeout',
               default=30,
               help=_("Tomcat session timeout in minutes.")),
    cfg.IntOpt('sync_timeout',
               default=10,
               help=_("(V2 driver) Sync thread timeout in seconds.")),
    cfg.IntOpt('retry_count',
               default=5,
               help=_("(V2 driver) Number of times to retry a row "
                      "before failing.")),
Example #20
0
#         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_config import cfg

from networking_odl._i18n import _


odl_opts = [
    cfg.StrOpt('url',
               help=_("HTTP URL of OpenDaylight REST interface.")),
    cfg.StrOpt('username',
               help=_("HTTP username for authentication.")),
    cfg.StrOpt('password', secret=True,
               help=_("HTTP password for authentication.")),
    cfg.IntOpt('timeout', default=10,
               help=_("HTTP timeout in seconds.")),
    cfg.IntOpt('session_timeout', default=30,
               help=_("Tomcat session timeout in minutes.")),
    cfg.FloatOpt('sync_timeout', default=10,
                 help=_("Sync thread timeout in seconds or fraction.")),
    cfg.IntOpt('retry_count', default=5,
               help=_("Number of times to retry a row before failing.")),
    cfg.IntOpt('maintenance_interval', default=300,
               help=_("Journal maintenance operations interval in seconds.")),
    cfg.IntOpt('completed_rows_retention', default=0,
Example #21
0
        python analyze_journal.py --file /path/to/file.log
"""

import collections
import re
import sys

import six

from oslo_config import cfg

from networking_odl._i18n import _
from networking_odl.journal import journal

COMMAND_LINE_OPTIONS = [
    cfg.StrOpt('file', default=None, help=_("Log file to analyze.")),
    cfg.IntOpt('slowest',
               min=1,
               default=10,
               help=_("Prints the N slowest entries (10 by default).")),
]

# This regex will match any replacement key in the log message and extract
# the key name.
KEY_MATCHER = re.compile(r'\%\((\S+)\)s')
LOG_KEYS = KEY_MATCHER.findall(journal.LOG_ENTRY_TEMPLATE)
KEY_TEMP_PATTERN = 'KEYPATTERN'
LOG_MATCHER = re.compile(
    re.sub(
        KEY_TEMP_PATTERN, r'(\\S+)',
        re.escape(KEY_MATCHER.sub(KEY_TEMP_PATTERN,