This file is indexed.

/usr/lib/python2.7/dist-packages/quickstart/juju.py is in juju-quickstart 1.3.1-0ubuntu1.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
# This file is part of the Juju Quickstart Plugin, which lets users set up a
# Juju environment in very few steps (https://launchpad.net/juju-quickstart).
# Copyright (C) 2013 Canonical Ltd.
#
# This program is free software: you can redistribute it and/or modify it under
# the terms of the GNU Affero General Public License version 3, as published by
# the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
# SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
# Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.

"""Juju Quickstart API client."""

from __future__ import unicode_literals

import logging

import jujuclient
import websocket


def connect(api_url):
    """Return an Environment instance connected to the given API URL."""
    connection = WebSocketConnection()
    # See the websocket.create_connection function.
    connection.settimeout(websocket.default_timeout)
    connection.connect(api_url, origin=api_url)
    return Environment(api_url, conn=connection)


class Environment(jujuclient.Environment):
    """A Juju bootstrapped environment.

    Instances of this class can be used to run API operations on a Juju
    environment. Specifically this subclass enables bundle support and
    deployments to specific machines.
    """

    def deploy_bundle(self, yaml, name=None, bundle_id=None):
        """Deploy a bundle."""
        params = {'YAML': yaml}
        if name is not None:
            params['Name'] = name
        if bundle_id is not None:
            params['BundleID'] = bundle_id
        request = {
            'Type': 'Deployer',
            'Request': 'Import',
            'Params': params,
        }
        return self._rpc(request)

    def create_auth_token(self):
        """Make an auth token creation request.

        Here is an example of a successful token creation response.

            {
                'RequestId': 42,
                'Response': {
                    'Token': 'TOKEN-STRING',
                    'Created': '2013-11-21T12:34:46.778866Z',
                    'Expires': '2013-11-21T12:36:46.778866Z'
                }
            }
        """
        request = dict(Type='GUIToken', Request='Create')
        return self._rpc(request)

    def get_watcher(self):
        """Return a connected/authenticated environment watcher.

        This method is similar to jujuclient.Environment.get_watch, but it
        enables logging on the resulting watcher requests/responses traffic.
        """
        # Logging is enabled by the connect factory function, which uses our
        # customized WebSocketConnection. Note that, since jujuclient does not
        # track request identifiers, it is not currently possible to avoid
        # establishing a new connection for each watcher.
        env = connect(self.endpoint)
        # For the remaining bits, see jujuclient.Environment.get_watch.
        env.login(**self._creds)
        watcher = jujuclient.Watcher(env.conn)
        self._watches.append(watcher)
        watcher.start()
        return watcher

    def get_status(self):
        """Return the current status of the environment.

        The status is represented by a single mega-watcher changeset.
        Each change in the changeset is a tuple (entity, action, data) where:
            - entity is a string representing the changed content type
              (e.g. "service" or "unit");
            - action is a string representing the event which generated the
              change (i.e. "change" or "remove");
            - data is a dict containing information about the releated entity.
        """
        with self.get_watcher() as watcher:
            changeset = watcher.next()
        return changeset

    def watch_changes(self, processor):
        """Start watching the changes occurring in the Juju environment.

        For each changeset, call the given processor callable, and yield
        the values returned by the processor.
        """
        with self.get_watcher() as watcher:
            # The watcher closes when the context manager exit hook is called.
            for changeset in watcher:
                changes = processor(changeset)
                if changes:
                    yield changes


class WebSocketConnection(websocket.WebSocket):
    """A WebSocket client connection."""

    def send(self, message):
        """Send the given WebSocket message.

        Overridden to add logging.
        """
        logging.debug('API message: --> {}'.format(message.decode('utf-8')))
        return super(WebSocketConnection, self).send(message)

    def recv(self):
        """Receive a message from the WebSocket server.

        Overridden to add logging.
        """
        message = super(WebSocketConnection, self).recv()
        logging.debug('API message: <-- {}'.format(message.decode('utf-8')))
        return message