~ubuntu-branches/ubuntu/vivid/ironic/vivid-updates

« back to all changes in this revision

Viewing changes to ironic/openstack/common/network_utils.py

  • Committer: Package Import Robot
  • Author(s): Chuck Short
  • Date: 2015-03-30 11:14:57 UTC
  • mfrom: (1.2.6)
  • Revision ID: package-import@ubuntu.com-20150330111457-kr4ju3guf22m4vbz
Tags: 2015.1~b3-0ubuntu1
* New upstream release.
  + d/control: 
    - Align with upstream dependencies.
    - Add dh-python to build-dependencies.
    - Add psmisc as a dependency. (LP: #1358820)
  + d/p/fix-requirements.patch: Rediffed.
  + d/ironic-conductor.init.in: Fixed typos in LSB headers,
    thanks to JJ Asghar. (LP: #1429962)

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright 2012 OpenStack Foundation.
2
 
# All Rights Reserved.
3
 
#
4
 
#    Licensed under the Apache License, Version 2.0 (the "License"); you may
5
 
#    not use this file except in compliance with the License. You may obtain
6
 
#    a copy of the License at
7
 
#
8
 
#         http://www.apache.org/licenses/LICENSE-2.0
9
 
#
10
 
#    Unless required by applicable law or agreed to in writing, software
11
 
#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12
 
#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13
 
#    License for the specific language governing permissions and limitations
14
 
#    under the License.
15
 
 
16
 
"""
17
 
Network-related utilities and helper functions.
18
 
"""
19
 
 
20
 
import logging
21
 
import socket
22
 
 
23
 
from six.moves.urllib import parse
24
 
 
25
 
from ironic.openstack.common.gettextutils import _LW
26
 
 
27
 
LOG = logging.getLogger(__name__)
28
 
 
29
 
 
30
 
def parse_host_port(address, default_port=None):
31
 
    """Interpret a string as a host:port pair.
32
 
 
33
 
    An IPv6 address MUST be escaped if accompanied by a port,
34
 
    because otherwise ambiguity ensues: 2001:db8:85a3::8a2e:370:7334
35
 
    means both [2001:db8:85a3::8a2e:370:7334] and
36
 
    [2001:db8:85a3::8a2e:370]:7334.
37
 
 
38
 
    >>> parse_host_port('server01:80')
39
 
    ('server01', 80)
40
 
    >>> parse_host_port('server01')
41
 
    ('server01', None)
42
 
    >>> parse_host_port('server01', default_port=1234)
43
 
    ('server01', 1234)
44
 
    >>> parse_host_port('[::1]:80')
45
 
    ('::1', 80)
46
 
    >>> parse_host_port('[::1]')
47
 
    ('::1', None)
48
 
    >>> parse_host_port('[::1]', default_port=1234)
49
 
    ('::1', 1234)
50
 
    >>> parse_host_port('2001:db8:85a3::8a2e:370:7334', default_port=1234)
51
 
    ('2001:db8:85a3::8a2e:370:7334', 1234)
52
 
    >>> parse_host_port(None)
53
 
    (None, None)
54
 
    """
55
 
    if not address:
56
 
        return (None, None)
57
 
 
58
 
    if address[0] == '[':
59
 
        # Escaped ipv6
60
 
        _host, _port = address[1:].split(']')
61
 
        host = _host
62
 
        if ':' in _port:
63
 
            port = _port.split(':')[1]
64
 
        else:
65
 
            port = default_port
66
 
    else:
67
 
        if address.count(':') == 1:
68
 
            host, port = address.split(':')
69
 
        else:
70
 
            # 0 means ipv4, >1 means ipv6.
71
 
            # We prohibit unescaped ipv6 addresses with port.
72
 
            host = address
73
 
            port = default_port
74
 
 
75
 
    return (host, None if port is None else int(port))
76
 
 
77
 
 
78
 
class ModifiedSplitResult(parse.SplitResult):
79
 
    """Split results class for urlsplit."""
80
 
 
81
 
    # NOTE(dims): The functions below are needed for Python 2.6.x.
82
 
    # We can remove these when we drop support for 2.6.x.
83
 
    @property
84
 
    def hostname(self):
85
 
        netloc = self.netloc.split('@', 1)[-1]
86
 
        host, port = parse_host_port(netloc)
87
 
        return host
88
 
 
89
 
    @property
90
 
    def port(self):
91
 
        netloc = self.netloc.split('@', 1)[-1]
92
 
        host, port = parse_host_port(netloc)
93
 
        return port
94
 
 
95
 
 
96
 
def urlsplit(url, scheme='', allow_fragments=True):
97
 
    """Parse a URL using urlparse.urlsplit(), splitting query and fragments.
98
 
    This function papers over Python issue9374 when needed.
99
 
 
100
 
    The parameters are the same as urlparse.urlsplit.
101
 
    """
102
 
    scheme, netloc, path, query, fragment = parse.urlsplit(
103
 
        url, scheme, allow_fragments)
104
 
    if allow_fragments and '#' in path:
105
 
        path, fragment = path.split('#', 1)
106
 
    if '?' in path:
107
 
        path, query = path.split('?', 1)
108
 
    return ModifiedSplitResult(scheme, netloc,
109
 
                               path, query, fragment)
110
 
 
111
 
 
112
 
def set_tcp_keepalive(sock, tcp_keepalive=True,
113
 
                      tcp_keepidle=None,
114
 
                      tcp_keepalive_interval=None,
115
 
                      tcp_keepalive_count=None):
116
 
    """Set values for tcp keepalive parameters
117
 
 
118
 
    This function configures tcp keepalive parameters if users wish to do
119
 
    so.
120
 
 
121
 
    :param tcp_keepalive: Boolean, turn on or off tcp_keepalive. If users are
122
 
      not sure, this should be True, and default values will be used.
123
 
 
124
 
    :param tcp_keepidle: time to wait before starting to send keepalive probes
125
 
    :param tcp_keepalive_interval: time between successive probes, once the
126
 
      initial wait time is over
127
 
    :param tcp_keepalive_count: number of probes to send before the connection
128
 
      is killed
129
 
    """
130
 
 
131
 
    # NOTE(praneshp): Despite keepalive being a tcp concept, the level is
132
 
    # still SOL_SOCKET. This is a quirk.
133
 
    if isinstance(tcp_keepalive, bool):
134
 
        sock.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, tcp_keepalive)
135
 
    else:
136
 
        raise TypeError("tcp_keepalive must be a boolean")
137
 
 
138
 
    if not tcp_keepalive:
139
 
        return
140
 
 
141
 
    # These options aren't available in the OS X version of eventlet,
142
 
    # Idle + Count * Interval effectively gives you the total timeout.
143
 
    if tcp_keepidle is not None:
144
 
        if hasattr(socket, 'TCP_KEEPIDLE'):
145
 
            sock.setsockopt(socket.IPPROTO_TCP,
146
 
                            socket.TCP_KEEPIDLE,
147
 
                            tcp_keepidle)
148
 
        else:
149
 
            LOG.warning(_LW('tcp_keepidle not available on your system'))
150
 
    if tcp_keepalive_interval is not None:
151
 
        if hasattr(socket, 'TCP_KEEPINTVL'):
152
 
            sock.setsockopt(socket.IPPROTO_TCP,
153
 
                            socket.TCP_KEEPINTVL,
154
 
                            tcp_keepalive_interval)
155
 
        else:
156
 
            LOG.warning(_LW('tcp_keepintvl not available on your system'))
157
 
    if tcp_keepalive_count is not None:
158
 
        if hasattr(socket, 'TCP_KEEPCNT'):
159
 
            sock.setsockopt(socket.IPPROTO_TCP,
160
 
                            socket.TCP_KEEPCNT,
161
 
                            tcp_keepalive_count)
162
 
        else:
163
 
            LOG.warning(_LW('tcp_keepknt not available on your system'))