<commit_before>'''
OpenStack Cloud Module
======================

The OpenStack cloud module. OpenStack is an open source project that is in  use
by a number a cloud providers, each of which have their own ways of using it.

OpenStack provides a number of ways to authenticate. This module uses password-
based authentication, using auth v2.0. It is likely to start supporting other
methods of authentication provided by OpenStack in the future.

Note that there is currently a dependency upon netaddr. This can be installed
on Debian-based systems by means of the python-netaddr package.

This module has been tested to work with HP Cloud and Rackspace. See the
documentation for specific options for either of these providers. Some examples
are provided below:

.. code-block:: yaml

    # The OpenStack identity service url
    OPENSTACK.identity_url: https://region-a.geo-1.identity.hpcloudsvc.com:35357/v2.0/
    # The OpenStack compute region
    OPENSTACK.compute_region: az-1.region-a.geo-1
    # The OpenStack compute service name
    OPENSTACK.compute_name: Compute
    # The OpenStack tenant name (not tenant ID)
    OPENSTACK.tenant: myuser-tenant1
    # The OpenStack user name
    OPENSTACK.user: myuser
    # The OpenStack keypair name
    OPENSTACK.ssh_key_name

Either a password or an API key must also be specified:

.. code-block:: yaml

    # The OpenStack password
    OPENSTACK.password: <PASSWORD>
    # The OpenStack API key
    OPENSTACK.apikey: 901d3f579h23c8v73q9

For local installations that only use private IP address ranges, the
following option may be useful:

.. code-block:: yaml

    # Ignore IP addresses on this network for bootstrap
    OPENSTACK.ignore_ip_addr: 192.168.50.0/24
'''

# The import section is mostly libcloud boilerplate

# Import python libs
import time
import sys
import logging
import socket

# Import libcloud
from libcloud.compute.base import NodeState

# Import generic libcloud functions
from saltcloud.libcloudfuncs import *

# Import salt libs
from salt.exceptions import SaltException

# Import saltcloud libs
from saltcloud.utils import namespaced_function

# Import netaddr IP matching
from netaddr import all_matching_cidrs

# Get logging started
log = logging.getLogger(__name__)


# Some of the libcloud functions need to be in the same namespace as the
# functions defined in the module, so we create new function objects inside
# this module namespace
avail_images = namespaced_function(avail_images, globals())
avail_sizes = namespaced_function(avail_sizes, globals())
script = namespaced_function(script, globals())
destroy = namespaced_function(destroy, globals())
list_nodes = namespaced_function(list_nodes, globals())
list_nodes_full = namespaced_function(list_nodes_full, globals())
list_nodes_select = namespaced_function(list_nodes_select, globals())


# Only load in this module is the OPENSTACK configurations are in place
def __virtual__():
    '''
    Set up the libcloud functions and check for OPENSTACK configs
    '''
    if 'OPENSTACK.user' in __opts__:
        log.debug('Loading Openstack cloud module')
        return 'openstack'
    return False


def get_conn():
    '''
    Return a conn object for the passed VM data
    '''
    driver = get_driver(Provider.OPENSTACK)
    authinfo = {
            'ex_force_auth_url': __opts__['OPENSTACK.identity_url'],
            }

    if 'OPENSTACK.compute_name' in __opts__:
        authinfo['ex_force_service_name'] = __opts__['OPENSTACK.compute_name']

    if 'OPENSTACK.compute_region' in __opts__:
        authinfo['ex_force_service_region'] = __opts__['OPENSTACK.compute_region']

    if 'OPENSTACK.tenant' in __opts__:
        authinfo['ex_tenant_name'] = __opts__['OPENSTACK.tenant']

    if 'OPENSTACK.password' in __opts__:
        authinfo['ex_force_auth_version'] = '2.0_password'
        log.debug('OpenStack authenticating using password')
        return driver(
            __opts__['OPENSTACK.user'],
            __opts__['OPENSTACK.password'],
            **authinfo
            )
    elif 'OPENSTACK.apikey' in __opts__:
        authinfo['ex_force_auth_version'] = '2.0_apikey'
        log.debug('OpenStack authenticating using apikey')
        return driver(
            __opts__['OPENSTACK.user'],
            __opts__['OPENSTACK.apikey'],
            **authinfo
            )


def preferred_ip(vm_, ips):
    '''
    Return the preferred Internet protocol. Either 'ipv4' (default) or 'ipv6'.
    '''
    proto = vm_.get('protocol', __opts__.get('OPENSTACK.protocol', 'ipv4'))
    family = socket.AF_INET
    if proto == 'ipv6':
        family = socket.AF_INET6
    for ip in ips:
        try:
            socket.inet_pton(family, ip)
            return ip
        except:
            continue
    return False


def ignore_ip_addr(vm_, ip):
    '''
    Return True if we are to ignore the specified IP. Compatible with IPv4.
    '''

    cidr = vm_.get('ip_ignore', __opts__.get('OPENSTACK.ignore_cidr', ''))
    if cidr != '' and all_matching_cidrs(ip, [cidr]):<commit_msg>Make netaddr an optional dependency<commit_after>'''
OpenStack Cloud Module
======================

The OpenStack cloud module. OpenStack is an open source project that is in  use
by a number a cloud providers, each of which have their own ways of using it.

OpenStack provides a number of ways to authenticate. This module uses password-
based authentication, using auth v2.0. It is likely to start supporting other
methods of authentication provided by OpenStack in the future.

Note that there is currently a dependency upon netaddr. This can be installed
on Debian-based systems by means of the python-netaddr package.

This module has been tested to work with HP Cloud and Rackspace. See the
documentation for specific options for either of these providers. Some examples
are provided below:

.. code-block:: yaml

    # The OpenStack identity service url
    OPENSTACK.identity_url: https://region-a.geo-1.identity.hpcloudsvc.com:35357/v2.0/
    # The OpenStack compute region
    OPENSTACK.compute_region: az-1.region-a.geo-1
    # The OpenStack compute service name
    OPENSTACK.compute_name: Compute
    # The OpenStack tenant name (not tenant ID)
    OPENSTACK.tenant: myuser-tenant1
    # The OpenStack user name
    OPENSTACK.user: myuser
    # The OpenStack keypair name
    OPENSTACK.ssh_key_name

Either a password or an API key must also be specified:

.. code-block:: yaml

    # The OpenStack password
    OPENSTACK.password: <PASSWORD>
    # The OpenStack API key
    OPENSTACK.apikey: <KEY>

For local installations that only use private IP address ranges, the
following option may be useful:

.. code-block:: yaml

    # Ignore IP addresses on this network for bootstrap
    OPENSTACK.ignore_ip_addr: 192.168.50.0/24
'''

# The import section is mostly libcloud boilerplate

# Import python libs
import time
import sys
import logging
import socket

# Import libcloud
from libcloud.compute.base import NodeState

# Import generic libcloud functions
from saltcloud.libcloudfuncs import *

# Import salt libs
from salt.exceptions import SaltException

# Import saltcloud libs
from saltcloud.utils import namespaced_function

# Import netaddr IP matching
try:
    from netaddr import all_matching_cidrs
    HAS_NETADDR = True
except:
    HAS_NETADDR = False

# Get logging started
log = logging.getLogger(__name__)


# Some of the libcloud functions need to be in the same namespace as the
# functions defined in the module, so we create new function objects inside
# this module namespace
avail_images = namespaced_function(avail_images, globals())
avail_sizes = namespaced_function(avail_sizes, globals())
script = namespaced_function(script, globals())
destroy = namespaced_function(destroy, globals())
list_nodes = namespaced_function(list_nodes, globals())
list_nodes_full = namespaced_function(list_nodes_full, globals())
list_nodes_select = namespaced_function(list_nodes_select, globals())


# Only load in this module is the OPENSTACK configurations are in place
def __virtual__():
    '''
    Set up the libcloud functions and check for OPENSTACK configs
    '''
    if 'OPENSTACK.user' in __opts__:
        log.debug('Loading Openstack cloud module')
        return 'openstack'
    return False


def get_conn():
    '''
    Return a conn object for the passed VM data
    '''
    driver = get_driver(Provider.OPENSTACK)
    authinfo = {
            'ex_force_auth_url': __opts__['OPENSTACK.identity_url'],
            }

    if 'OPENSTACK.compute_name' in __opts__:
        authinfo['ex_force_service_name'] = __opts__['OPENSTACK.compute_name']

    if 'OPENSTACK.compute_region' in __opts__:
        authinfo['ex_force_service_region'] = __opts__['OPENSTACK.compute_region']

    if 'OPENSTACK.tenant' in __opts__:
        authinfo['ex_tenant_name'] = __opts__['OPENSTACK.tenant']

    if 'OPENSTACK.password' in __opts__:
        authinfo['ex_force_auth_version'] = '2.0_password'
        log.debug('OpenStack authenticating using password')
        return driver(
            __opts__['OPENSTACK.user'],
            __opts__['OPENSTACK.password'],
            **authinfo
            )
    elif 'OPENSTACK.apikey' in __opts__:
        authinfo['ex_force_auth_version'] = '2.0_apikey'
        log.debug('OpenStack authenticating using apikey')
        return driver(
            __opts__['OPENSTACK.user'],
            __opts__['OPENSTACK.apikey'],
            **authinfo
            )


def preferred_ip(vm_, ips):
    '''
    Return the preferred Internet protocol. Either 'ipv4' (default) or 'ipv6'.
    '''
    proto = vm_.get('protocol', __opts__.get('OPENSTACK.protocol', 'ipv4'))
    family = socket.AF_INET
    if proto == 'ipv6':
        family = socket.AF_INET6
    for ip in ips:
        try:
            socket.inet_pton(family, ip)
            return ip
        except:
            continue
    return False


def ignore_ip_addr(vm_, ip):
    '''
    Return True if we are to ignore the specified IP. Compatible with IPv4.
    '''
    if HAS_NETADDR is False:
        return 'Error: netaddr is not installed'

    cidr = vm_.get('ip_ignore', __opts__.get('OPENSTACK.ignore_cidr', ''))
    if cidr != '' and all_matching_cidrs(ip, [cidr]):
{'fraction_non_alphanumeric': 0.08400234971607598, 'fraction_numerical': 0.007930291756412767, 'mean_word_length': 3.4665500655881067, 'pattern_counts': {'":': 0, '<': 6, '<?xml version=': 0, '>': 6, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 2, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '640788', 'n_tokens_mistral': 3079, 'n_tokens_neox': 2964, 'n_words': 979}