<commit_before>import base64
import shlex

try:
    import simplejson as json
except:
    import json

from libcloud.utils.py3 import httplib
from libcloud.utils.py3 import b

from libcloud.common.base import JsonResponse, ConnectionUserAndKey
from libcloud.common.types import InvalidCredsError

from libcloud.container.base import (Container, ContainerDriver,
                                     ContainerImage)

from libcloud.container.providers import Provider
from libcloud.container.types import ContainerState

VALID_RESPONSE_CODES = [httplib.OK, httplib.ACCEPTED, httplib.CREATED,
                        httplib.NO_CONTENT]


class RancherResponse(JsonResponse):

    def parse_body(self):
        if len(self.body) == 0 and not self.parse_zero_length_body:
            return self.body
        valid_content_types = ['application/json',
                               'application/json; charset=utf-8']
        content_type = self.headers.get('content-type')
        if content_type in valid_content_types:
            return json.loads(self.body)

    def parse_error(self):
        if self.status == 401:
            raise InvalidCredsError('Invalid credentials')
        return self.body

    def success(self):
        return self.status in VALID_RESPONSE_CODES


class RancherException(Exception):

    def __init__(self, code, message):
        self.code = code
        self.message = message
        self.args = (code, message)

    def __str__(self):
        return "%s %s" % (self.code, self.message)

    def __repr__(self):
        return "RancherException %s %s" % (self.code, self.message)


class RancherConnection(ConnectionUserAndKey):

    responseCls = RancherResponse
    timeout = 30

    def add_default_headers(self, headers):
        """
        Add parameters that are necessary for every request
        If user and password are specified, include a base http auth
        header
        """
        headers['Content-Type'] = 'application/json'
        headers['Accept'] = 'application/json'
        if self.key and self.user_id:
            user_b64 = base64.b64encode(b('%s:%s' % (self.user_id, self.key)))
            headers['Authorization'] = 'Basic %s' % (user_b64.decode('utf-8'))
        return headers


class RancherContainerDriver(ContainerDriver):

    type = Provider.RANCHER
    name = 'Rancher'
    website = 'http://rancher.com'
    connectionCls = RancherConnection
    # Holding off on cluster support for now.
    # Only Environment API interaction enabled.
    supports_clusters = False
    # As in the /v1/
    version = '1'

    def __init__(self, key, secret, secure=False, host='localhost', port=80):
        """
        Rancher Container driver class.

        Example:

        >>> from libcloud.container.providers import get_driver
        >>> from libcloud.container.types import Provider

        >>> driver = get_driver(Provider.RANCHER)
        >>> connection = driver(key="ACCESS_KEY_HERE",
        secret="SECRET_KEY_HERE", host="172.30.0.100", port=8080)

        >>> image = ContainerImage("hastebin", "hastebin", "rlister/hastebin",
        "latest", driver=None)
        >>> newcontainer = connection.deploy_container("myawesomepastebin",
        image, environment={"STORAGE_TYPE": "file"})

        :param    key: API key or username to used (required)
        :type     key: ``str``

        :param    secret: Secret password to be used (required)
        :type     secret: ``str``

        :param    secure: Whether to use HTTPS or HTTP.
        :type     secure: ``bool``

        :param    host: Override hostname used for connections.
        :type     host: ``str``

        :param    port: Override port used for connections.
        :type     port: ``int``


        :return: ``None``
        """
        super(RancherContainerDriver, self).__init__(key=key, secret=secret,
                                                     secure=secure, host=host,
                                                     port=port)
        if host.startswith('https://'):
            secure = True

        # strip the prefix
        prefixes = ['http://', 'https://']
        for prefix in prefixes:
            if host.startswith(prefix):
                host = host.strip(prefix)

        self.connection.host = host
        self.connection.port = port
        self.connection.secure = secure

        # We only support environment api keys, meaning none of this:
        # self.baseuri = "/v%s/projects/%s" % (self.version, project_id)
        self.baseuri = "/v%s" % self.version

    def ex_list_environments(self):
        """
        List all Rancher Environments (called "Stacks" in the UI)

        http://docs.rancher.com/rancher/v1.2/en/api/api-resources/environment/

        :rtype: ``list`` of ``dict``
        """

        result = self.connection.request(
            "%s/environments" % self.baseuri).object
        return result['data']

    def ex_deploy_environment(self, name, description=None, dockercompose=None,<commit_msg>secure by default<commit_after>import base64
import shlex

try:
    import simplejson as json
except:
    import json

from libcloud.utils.py3 import httplib
from libcloud.utils.py3 import b

from libcloud.common.base import JsonResponse, ConnectionUserAndKey
from libcloud.common.types import InvalidCredsError

from libcloud.container.base import (Container, ContainerDriver,
                                     ContainerImage)

from libcloud.container.providers import Provider
from libcloud.container.types import ContainerState

VALID_RESPONSE_CODES = [httplib.OK, httplib.ACCEPTED, httplib.CREATED,
                        httplib.NO_CONTENT]


class RancherResponse(JsonResponse):

    def parse_body(self):
        if len(self.body) == 0 and not self.parse_zero_length_body:
            return self.body
        valid_content_types = ['application/json',
                               'application/json; charset=utf-8']
        content_type = self.headers.get('content-type')
        if content_type in valid_content_types:
            return json.loads(self.body)

    def parse_error(self):
        if self.status == 401:
            raise InvalidCredsError('Invalid credentials')
        return self.body

    def success(self):
        return self.status in VALID_RESPONSE_CODES


class RancherException(Exception):

    def __init__(self, code, message):
        self.code = code
        self.message = message
        self.args = (code, message)

    def __str__(self):
        return "%s %s" % (self.code, self.message)

    def __repr__(self):
        return "RancherException %s %s" % (self.code, self.message)


class RancherConnection(ConnectionUserAndKey):

    responseCls = RancherResponse
    timeout = 30

    def add_default_headers(self, headers):
        """
        Add parameters that are necessary for every request
        If user and password are specified, include a base http auth
        header
        """
        headers['Content-Type'] = 'application/json'
        headers['Accept'] = 'application/json'
        if self.key and self.user_id:
            user_b64 = base64.b64encode(b('%s:%s' % (self.user_id, self.key)))
            headers['Authorization'] = 'Basic %s' % (user_b64.decode('utf-8'))
        return headers


class RancherContainerDriver(ContainerDriver):

    type = Provider.RANCHER
    name = 'Rancher'
    website = 'http://rancher.com'
    connectionCls = RancherConnection
    # Holding off on cluster support for now.
    # Only Environment API interaction enabled.
    supports_clusters = False
    # As in the /v1/
    version = '1'

    def __init__(self, key, secret, secure=True, host='localhost', port=443):
        """
        Rancher Container driver class.

        Example:

        >>> from libcloud.container.providers import get_driver
        >>> from libcloud.container.types import Provider

        >>> driver = get_driver(Provider.RANCHER)
        >>> connection = driver(key="ACCESS_KEY_HERE",
        secret="SECRET_KEY_HERE", host="172.30.0.100", port=8080)

        >>> image = ContainerImage("hastebin", "hastebin", "rlister/hastebin",
        "latest", driver=None)
        >>> newcontainer = connection.deploy_container("myawesomepastebin",
        image, environment={"STORAGE_TYPE": "file"})

        :param    key: API key or username to used (required)
        :type     key: ``str``

        :param    secret: Secret password to be used (required)
        :type     secret: ``str``

        :param    secure: Whether to use HTTPS or HTTP.
        :type     secure: ``bool``

        :param    host: Override hostname used for connections.
        :type     host: ``str``

        :param    port: Override port used for connections.
        :type     port: ``int``


        :return: ``None``
        """
        super(RancherContainerDriver, self).__init__(key=key, secret=secret,
                                                     secure=secure, host=host,
                                                     port=port)
        if host.startswith('http://'):
            secure = False

        # strip the prefix
        prefixes = ['http://', 'https://']
        for prefix in prefixes:
            if host.startswith(prefix):
                host = host.strip(prefix)

        self.connection.host = host
        self.connection.port = port
        self.connection.secure = secure

        # We only support environment api keys, meaning none of this:
        # self.baseuri = "/v%s/projects/%s" % (self.version, project_id)
        self.baseuri = "/v%s" % self.version

    def ex_list_environments(self):
        """
        List all Rancher Environments (called "Stacks" in the UI)

        http://docs.rancher.com/rancher/v1.2/en/api/api-resources/environment/

        :rtype: ``list`` of ``dict``
        """

        result = self.connection.request(
            "%s/environments" % self.baseuri).object
        return result['data']

    def ex_deploy_environment(self, name, description=None, dockercompose=None,
{'fraction_non_alphanumeric': 0.10480175333731818, 'fraction_numerical': 0.007870093644152221, 'mean_word_length': 2.309924167490933, 'pattern_counts': {'":': 2, '<': 3, '<?xml version=': 0, '>': 39, 'https://': 3, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 2, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 10, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1869197', 'n_tokens_mistral': 2900, 'n_tokens_neox': 2784, 'n_words': 723}