async def test_file_cred_v3(self, mock_cf):
     with NamedTemporaryFile() as tempfile:
         tempfile.close()
         temppath = Path(tempfile.name)
         temppath.write_text('cred-test')
         cred = client.CloudCredential(auth_type='jsonfile',
                                       attrs={'file': tempfile.name})
         jujudata = mock.MagicMock()
         c = Controller(jujudata=jujudata)
         c._connector = base.AsyncMock()
         up_creds = base.AsyncMock()
         cloud_facade = mock_cf.from_connection()
         cloud_facade.version = 3
         cloud_facade.UpdateCredentialsCheckModels = up_creds
         await c.add_credential(
             name='name',
             credential=cred,
             cloud='cloud',
             owner='owner',
             force=True,
         )
         assert up_creds.called
         assert up_creds.call_args[1]['force']
         new_cred = up_creds.call_args[1]['credentials'][0].credential
         assert cred.attrs['file'] == tempfile.name
         assert new_cred.attrs['file'] == 'cred-test'
async def test_redirect(event_loop):
    controller = Controller()
    await controller.connect()
    kwargs = controller.connection().connect_params()
    await controller.disconnect()

    # websockets.server.logger.setLevel(logging.DEBUG)
    # websockets.client.logger.setLevel(logging.DEBUG)
    # # websockets.protocol.logger.setLevel(logging.DEBUG)
    # logger.setLevel(logging.DEBUG)

    destination = 'wss://{}/api'.format(kwargs['endpoint'])
    redirect_statuses = [
        http.HTTPStatus.MOVED_PERMANENTLY,
        http.HTTPStatus.FOUND,
        http.HTTPStatus.SEE_OTHER,
        http.HTTPStatus.TEMPORARY_REDIRECT,
        http.HTTPStatus.PERMANENT_REDIRECT,
    ]
    test_server_cert = Path(__file__).with_name('cert.pem')
    kwargs['cacert'] += '\n' + test_server_cert.read_text()
    server = RedirectServer(destination, event_loop)
    try:
        for status in redirect_statuses:
            logger.debug('test: starting {}'.format(status))
            server.start(status)
            await run_with_interrupt(server.running.wait(),
                                     server.terminated)
            if server.exception:
                raise server.exception
            assert not server.terminated.is_set()
            logger.debug('test: started')
            kwargs_copy = dict(kwargs,
                               endpoint='localhost:{}'.format(server.port))
            logger.debug('test: connecting')
            conn = await Connection.connect(**kwargs_copy)
            logger.debug('test: connected')
            await conn.close()
            logger.debug('test: stopping')
            server.stop()
            await server.stopped.wait()
            logger.debug('test: stopped')
    finally:
        server.terminate()
        await server.terminated.wait()
async def test_macaroon_auth(event_loop):
    jujudata = FileJujuData()
    account = jujudata.accounts()[jujudata.current_controller()]
    with base.patch_file('~/.local/share/juju/accounts.yaml'):
        if 'password' in account:
            # force macaroon auth by "changing" password to current password
            result = subprocess.run(
                ['juju', 'change-user-password'],
                input='{0}\n{0}\n'.format(account['password']),
                universal_newlines=True,
                stderr=subprocess.PIPE)
            assert result.returncode == 0, ('Failed to change password: '******'{}'.format(result.stderr))
        controller = Controller()
        try:
            await controller.connect()
            assert controller.is_connected()
        finally:
            if controller.is_connected():
                await controller.disconnect()
        async with base.CleanModel():
            pass  # create and login to model works
async def test_change_user_password(event_loop):
    async with base.CleanController() as controller:
        username = '******'.format(uuid.uuid4())
        await controller.add_user(username)
        await controller.change_user_password(username, 'password')
        try:
            new_controller = Controller()
            await new_controller.connect(controller.connection.endpoint,
                                         username, 'password')
            result = True
            await new_controller.disconnect()
        except JujuAPIError:
            result = False
        assert result is True
 async def test_with_endpoint_and_macaroons(self, mock_connect, mock_update_endpoints):
     c = Controller()
     await c.connect(endpoint='0.1.2.3:4566',
                     macaroons=['macaroon'])
     mock_connect.assert_called_with(endpoint='0.1.2.3:4566',
                                     macaroons=['macaroon'])
     mock_update_endpoints.assert_called_with()
     await c.connect(endpoint='0.1.2.3:4566',
                     bakery_client='bakery',
                     macaroons=['macaroon'])
     mock_connect.assert_called_with(endpoint='0.1.2.3:4566',
                                     bakery_client='bakery',
                                     macaroons=['macaroon'])
     mock_update_endpoints.assert_called_with()
Exemple #6
0
async def async_cloud(name=None):
    """Return information about cloud.

    :param name: Cloud name. If not specified, the cloud where
                 the controller lives on is returned.
    :type name: Optional[str]
    :returns: Information on all clouds in the controller.
    :rtype: CloudResult
    """
    controller = Controller()
    await controller.connect()
    cloud = await controller.cloud(name=name)
    await controller.disconnect()
    return cloud
Exemple #7
0
async def main():
    controller = Controller()
    print("Connecting to controller")
    # connect to current controller with current user, per Juju CLI
    await controller.connect()

    try:
        model_name = "addmodeltest-{}".format(uuid.uuid4())
        print("Adding model {}".format(model_name))
        model = await controller.add_model(model_name)

        print('Deploying ubuntu')
        application = await model.deploy(
            'ubuntu-10',
            application_name='ubuntu',
            series='trusty',
            channel='stable',
        )

        print('Waiting for active')
        await asyncio.sleep(10)
        await model.block_until(lambda: all(unit.workload_status == 'active'
                                            for unit in application.units))

        print("Verifying that we can ssh into the created model")
        ret = await utils.execute_process('juju',
                                          'ssh',
                                          '-m',
                                          model_name,
                                          'ubuntu/0',
                                          'ls /',
                                          log=LOG)
        assert ret

        print('Removing ubuntu')
        await application.remove()

        print("Destroying model")
        await controller.destroy_model(model.info.uuid)

    except Exception:
        LOG.exception(
            "Test failed! Model {} may not be cleaned up".format(model_name))

    finally:
        print('Disconnecting from controller')
        if model:
            await model.disconnect()
        await controller.disconnect()
Exemple #8
0
    async def __aenter__(self):
        self.controller = Controller()
        await self.controller.connect_current()

        model_name = 'model-{}'.format(uuid.uuid4())
        self.model = await self.controller.add_model(model_name)

        # Ensure that we connect to the new model by default.  This also
        # prevents failures if test was started with no current model.
        self._patch_cm = mock.patch.object(JujuData,
                                           'current_model',
                                           return_value=model_name)
        self._patch_cm.start()

        return self.model
async def watch():
    controller = Controller()
    # connect to current
    # controller with current user, per Juju CLI
    await controller.connect()

    # Need to call the WatchModelSummaries or WatchAllModelSummaries on the
    # controller.
    def callback(summary):
        print("-- change --\n{}\n".format(summary))

    await controller.watch_model_summaries(callback)

    while True:
        await asyncio.sleep(1)
 async def test_file_cred_v2(self, mock_cf):
     with NamedTemporaryFile() as tempfile:
         tempfile.close()
         temppath = Path(tempfile.name)
         temppath.write_text('cred-test')
         cred = client.CloudCredential(auth_type='jsonfile',
                                       attrs={'file': tempfile.name})
         jujudata = mock.MagicMock()
         c = Controller(jujudata=jujudata)
         c._connector = base.AsyncMock()
         up_creds = base.AsyncMock()
         cloud_facade = mock_cf.from_connection()
         cloud_facade.version = 2
         cloud_facade.UpdateCredentials = up_creds
         await c.add_credential(
             name='name',
             credential=cred,
             cloud='cloud',
             owner='owner',
         )
         assert up_creds.called
         new_cred = up_creds.call_args[0][0][0].credential
         assert cred.attrs['file'] == tempfile.name
         assert new_cred.attrs['file'] == 'cred-test'
Exemple #11
0
async def model_available():
    """ Check whether selected model is already available.
    """
    if app.provider.controller is None:
        raise Exception("No controller selected")

    if app.provider.model is None:
        raise Exception("No model selected.")

    controller = Controller(app.loop)
    await controller.connect(app.provider.controller)
    try:
        models = await controller.list_models()
        return app.provider.model in models
    finally:
        await controller.disconnect()
Exemple #12
0
async def async_add_model(model_name, config=None):
    """Add a model to the current controller.

    :param model_name: Name to give the new model.
    :type model_name: str
    :param config: Model configuration.
    :type config: dict
    """
    controller = Controller()
    await controller.connect()
    logging.debug("Adding model {}".format(model_name))
    model = await controller.add_model(model_name, config=config)
    # issue/135 It is necessary to disconnect the model here or async spews
    # tracebacks even during a successful run.
    await model.disconnect()
    await controller.disconnect()
Exemple #13
0
async def run():
    controller = Controller()
    await controller.connect_current()
    model = await controller.add_model(
        'libjuju-test',
        'cloud-aws',
        'cloudcred-aws_tvansteenburgh@external_aws-tim',
    )
    await model.deploy(
        'ubuntu-0',
        service_name='ubuntu',
        series='trusty',
        channel='stable',
    )
    await model.disconnect()
    await controller.disconnect()
    model.loop.stop()
Exemple #14
0
async def main():
    controller = Controller()
    await controller.connect()
    model = await controller.add_model(
        'my-test-model',
        'aws',
        'aws-tim',
    )
    await model.deploy(
        'ubuntu-0',
        application_name='ubuntu',
        series='trusty',
        channel='stable',
    )
    await model.disconnect()
    await controller.destroy_model(model.info.uuid)
    await controller.disconnect()
Exemple #15
0
async def async_add_model(model_name, config=None):
    """Add a model to the current controller.

    :param model_name: Name to give the new model.
    :type model_name: str
    :param config: Model configuration.
    :type config: dict
    """
    controller = Controller()
    await controller.connect()
    logging.debug("Adding model {}".format(model_name))
    model = await controller.add_model(model_name, config=config)
    await model.disconnect()
    await controller.disconnect()
    # NOTE: This is necessary to guarantee juju is aware of the newly created
    # model.
    go_list_models()
Exemple #16
0
    async def connect(self):
        """Connect to the Juju controller."""
        controller = Controller()

        log("Connecting to controller... ws://{}:{} as {}/{}".format(
            self.endpoint,
            self.port,
            self.user,
            self.secret[-4:].rjust(len(self.secret), "*"),
        ))
        await controller.connect(
            endpoint=self.endpoint,
            username=self.user,
            password=self.secret,
            cacert=self.cacert,
        )

        return controller
Exemple #17
0
async def main():
    controller = Controller()
    await controller.connect()

    try:
        model = await controller.add_model("test-model")
        application = await model.deploy("ubuntu",
                                         constraints={"arch": "amd64"})

        print('Waiting for active')
        await model.block_until(lambda: all(unit.workload_status == 'active'
                                            for unit in application.units))
        print("Successfully deployed!")
        print('Removing bundle')
        await application.remove()
    finally:
        print('Disconnecting from controller')
        await controller.disconnect()
        print("Success")
Exemple #18
0
async def create_model():
    """ Creates the selected model.
    """
    if app.provider.controller is None:
        raise Exception("No controller selected")

    if app.provider.model is None:
        raise Exception("No model selected.")

    controller = Controller(app.loop)
    await controller.connect(app.provider.controller)
    try:
        app.juju.client = await controller.add_model(
            model_name=app.provider.model,
            cloud_name=app.provider.cloud,
            region=app.provider.region,
            credential_name=app.provider.credential)
        events.ModelConnected.set()
    finally:
        await controller.disconnect()
 async def test_with_posargs(self, mock_connect, mock_connect_controller):
     c = Controller()
     await c.connect('foo')
     mock_connect_controller.assert_called_once_with('foo')
     with self.assertRaises(TypeError):
         await c.connect('endpoint', 'user')
     await c.connect('endpoint', 'user', 'pass')
     mock_connect.assert_called_once_with(endpoint='endpoint',
                                          username='******',
                                          password='******')
     await c.connect('endpoint', 'user', 'pass', 'cacert', 'bakery',
                     'macaroons', 'loop', 'max_frame_size')
     mock_connect.assert_called_with(endpoint='endpoint',
                                     username='******',
                                     password='******',
                                     cacert='cacert',
                                     bakery_client='bakery',
                                     macaroons='macaroons',
                                     loop='loop',
                                     max_frame_size='max_frame_size')
Exemple #20
0
async def set_model_acc(c_name, m_name, access, user, username, password, url, port):
    try:
        controllers = redis.StrictRedis(host=url, port=port, charset="utf-8", decode_responses=True, db=10)
        users = redis.StrictRedis(host=url, port=port, charset="utf-8", decode_responses=True, db=11)
        controller = json.loads(controllers.get(c_name))
        usr = json.loads(users.get(user))
        for mod in controller['models']:
            if mod['name'] == m_name:
                model = Model()
                await model.connect(controller['endpoints'][0], mod['uuid'], username, password, controller['ca-cert'])
                await model.grant(user, acl=access)
                exists_con = False
                for con in usr['controllers']:
                    if con['name'] == c_name:
                        exists_mod = False
                        exists_con = True
                        for mod in con['models']:
                            if mod['name'] == m_name:
                                mod['access'] = access
                                exists_mod = True
                                break
                        if not exists_mod:
                            con['models'].append({'name': m_name, 'access': access})
                if not exists_con:
                    usr['controllers'].append({'name': c_name, 'access': 'login', 'models': [{'name': m_name, 'access': access}]})
                    contro = Controller()
                    await contro.connect(controller['endpoints'][0], username, password, controller['ca-cert'])
                    await contro.grant(user)
                    await contro.disconnect()
                logger.info('%s access granted on %s:%s for  %s', access, c_name, m_name, user)
                if access == 'admin' or access == 'write':
                    for key in usr['ssh-keys']:
                        await model.add_ssh_key(user, key)
                model.disconnect()
        controllers.set(c_name, json.dumps(controller))
        users.set(user, json.dumps(usr))
    except Exception:
        exc_type, exc_value, exc_traceback = sys.exc_info()
        lines = traceback.format_exception(exc_type, exc_value, exc_traceback)
        for l in lines:
            logger.error(l)
Exemple #21
0
async def temporary_model(log_dir, timeout=14400, force_cloud=''):
    ''' Create and destroy a temporary Juju model named cdk-build-upgrade-*.

    This is an async context, to be used within an `async with` statement.
    '''
    with timeout_for_current_task(timeout):
        controller = Controller()
        await controller.connect_current()
        model_name = 'cdk-build-upgrade-%d' % random.randint(0, 10000)
        model_config = {'test-mode': True}
        model = await add_model_via_cli(controller, model_name, model_config, force_cloud)
        cloud = await controller.get_cloud()
        if cloud == 'localhost':
            await asyncify(apply_profile)(model_name)
        try:
            async with captured_fail_logs(model, log_dir):
                await yield_(model)
        finally:
            await model.disconnect()
            await controller.destroy_model(model_name)
            await controller.disconnect()
Exemple #22
0
    async def login(self):
        """Login to the Juju controller."""
        if self.authenticated:
            return
        cacert = None
        self.controller = Controller()

        self.log.debug("JujuApi: Logging into controller")

        if self.secret:
            await self.controller.connect(
                self.endpoint,
                self.user,
                self.secret,
                cacert,
            )
        else:
            await self.controller.connect_current()

        self.authenticated = True
        self.model = await self.get_model(self.model_name)
Exemple #23
0
    async def get_controller(self, name, include_passwords=False):
        """Get a controller by name.

        :param str name: Name of controller
        :param bool include_passwords: Include passwords for accounts

        The returned controller will try and connect to be ready to use.
        """

        # check if name is in the controllers.yaml
        controllers = self.jujudata.controllers()
        assert isinstance(controllers, dict)
        if name not in controllers:
            raise JujuError('%s is not among the controllers: %s' %
                            (name, controllers.keys()))

        # make a new Controller object that's connected to the
        # controller with the given name
        controller = Controller()
        await controller.connect(name)
        return controller
Exemple #24
0
async def async_destroy_model(model_name):
    """Remove a model from the current controller.

    :param model_name: Name of model to remove
    :type model_name: str
    """
    controller = Controller()
    try:
        await controller.connect()
        logging.info("Destroying model {}".format(model_name))
        await controller.destroy_model(model_name,
                                       destroy_storage=True,
                                       force=True,
                                       max_wait=600)
        # The model ought to be destroyed by now.  Let's make sure, and if not,
        # raise an error.  Even if the model has been destroyed, it's still
        # hangs around in the .list_models() for a little while; retry until it
        # goes away, or that fails.
        attempt = 1
        while True:
            logging.info("Waiting for model to be fully destroyed: "
                         "attempt: {}".format(attempt))
            remaining_models = await controller.list_models()
            if model_name not in remaining_models:
                break
            await asyncio.sleep(10)
            attempt += 1
            if attempt > 20:
                raise zaza.utilities.exceptions.DestroyModelFailed(
                    "Destroying model {} failed.".format(model_name))

        logging.info("Model {} destroyed.".format(model_name))
    finally:
        try:
            await controller.disconnect()
        except Exception as e:
            logging.error("Couldn't disconnect from model: {}".format(str(e)))
Exemple #25
0
async def main(cloud_name, credential_name):
    controller = Controller()
    model = None
    print('Connecting to controller')
    # connect to current controller with current user, per Juju CLI
    await controller.connect()
    try:
        print('Adding model')
        model = await controller.add_model(
            'test',
            cloud_name=cloud_name,
            credential_name=credential_name)

        # verify credential
        print("Verify model's credential: {}".format(
            model.info.cloud_credential_tag))

        # verify we can deploy
        print('Deploying ubuntu')
        app = await model.deploy('ubuntu-10')

        print('Waiting for active')
        await model.block_until(
            lambda: app.units and all(unit.workload_status == 'active'
                                      for unit in app.units))

        print('Removing ubuntu')
        await app.remove()
    finally:
        print('Cleaning up')
        if model:
            print('Removing model')
            model_uuid = model.info.uuid
            await model.disconnect()
            await controller.destroy_model(model_uuid)
        print('Disconnecting')
        await controller.disconnect()
 async def test_controller_connect_no_args(self, mock_connect_controller):
     from juju.controller import Controller
     c = Controller()
     await c.connect()
     mock_connect_controller.assert_called_once_with(None)
 async def test_controller_connect_with_controller_name(
         self, mock_connect_controller):
     from juju.controller import Controller
     c = Controller()
     await c.connect(controller_name='foo')
     mock_connect_controller.assert_called_once_with('foo')
 async def test_with_endpoint_and_bakery_client(self, mock_connect):
     c = Controller()
     await c.connect(endpoint='0.1.2.3:4566', bakery_client='bakery')
     mock_connect.assert_called_once_with(endpoint='0.1.2.3:4566',
                                          bakery_client='bakery')
 async def test_with_endpoint_and_no_auth(self, mock_connect):
     c = Controller()
     with self.assertRaises(TypeError):
         await c.connect(endpoint='0.1.2.3:4566')
     self.assertEqual(mock_connect.call_count, 0)
 async def test_no_args(self, mock_connect_controller):
     c = Controller()
     await c.connect()
     mock_connect_controller.assert_called_once_with(None)
Exemple #31
0
 async def __aenter__(self):
     self._controller = Controller()
     await self._controller.connect()
     return self._controller
async def main():
    controller1 = Controller()
    print("Connecting to controller")
    await controller1.connect("test")

    controller2 = Controller()
    print("Connecting to controller")
    await controller2.connect("test2")

    try:
        print('Creating models')
        offering_model = await controller1.add_model('test-cmr-1')
        consuming_model = await controller2.add_model('test-cmr-2')

        print('Deploying mysql')
        application = await offering_model.deploy(
            'cs:mysql',
            application_name='mysql',
            series='trusty',
            channel='stable',
        )

        print('Waiting for active')
        await offering_model.block_until(lambda: all(
            unit.workload_status == 'active' for unit in application.units))

        print('Adding offer')
        await offering_model.create_offer("mysql:db")

        offers = await offering_model.list_offers()
        print(
            'Show offers', ', '.join("%s: %s" % item
                                     for offer in offers.results
                                     for item in vars(offer).items()))

        print('Consuming offer')
        await consuming_model.consume("admin/test-cmr-1.mysql",
                                      controller_name="test")

        print('Exporting bundle')
        with tempfile.TemporaryDirectory() as dirpath:
            await offering_model.export_bundle("{}/bundle.yaml".format(dirpath)
                                               )

        print("Remove SAAS")
        await consuming_model.remove_saas("mysql")

        print('Removing offer')
        await offering_model.remove_offer("admin/test-cmr-1.mysql", force=True)

        print('Destroying models')
        await controller1.destroy_model(offering_model.info.uuid)
        await controller2.destroy_model(consuming_model.info.uuid)

    except Exception:
        log.exception("Example failed!")
        raise

    finally:
        print('Disconnecting from controller')
        await controller1.disconnect()
        await controller2.disconnect()
 async def test_with_controller_name(self, mock_connect_controller, mock_update_endpoints):
     c = Controller()
     await c.connect(controller_name='foo')
     mock_connect_controller.assert_called_once_with('foo')
     mock_update_endpoints.assert_called_once_with()