Note: Any connection method or constructor can accept an optional `loop`
argument to override the default event loop from `asyncio.get_event_loop`.
"""
+
+ DEFAULT_FRAME_SIZE = 'default_frame_size'
+ MAX_FRAME_SIZE = 2**22
+ "Maximum size for a single frame. Defaults to 4MB."
+
def __init__(
self, endpoint, uuid, username, password, cacert=None,
- macaroons=None, loop=None):
+ macaroons=None, loop=None, max_frame_size=DEFAULT_FRAME_SIZE):
self.endpoint = endpoint
self.uuid = uuid
if macaroons:
self.facades = {}
self.messages = IdQueue(loop=self.loop)
self.monitor = Monitor(connection=self)
+ if max_frame_size is self.DEFAULT_FRAME_SIZE:
+ max_frame_size = self.MAX_FRAME_SIZE
+ self.max_frame_size = max_frame_size
@property
def is_open(self):
kw = dict()
kw['ssl'] = self._get_ssl(self.cacert)
kw['loop'] = self.loop
+ kw['max_size'] = self.max_frame_size
self.addr = url
self.ws = await websockets.connect(url, **kw)
self.loop.create_task(self.receiver())
self.cacert,
self.macaroons,
self.loop,
+ self.max_frame_size,
)
async def controller(self):
@classmethod
async def connect(
cls, endpoint, uuid, username, password, cacert=None,
- macaroons=None, loop=None):
+ macaroons=None, loop=None, max_frame_size=None):
"""Connect to the websocket.
If uuid is None, the connection will be to the controller. Otherwise it
"""
client = cls(endpoint, uuid, username, password, cacert, macaroons,
- loop)
+ loop, max_frame_size)
endpoints = [(endpoint, cacert)]
while endpoints:
_endpoint, _cacert = endpoints.pop(0)
return client
@classmethod
- async def connect_current(cls, loop=None):
+ async def connect_current(cls, loop=None, max_frame_size=None):
"""Connect to the currently active model.
"""
model_name = jujudata.current_model()
return await cls.connect_model(
- '{}:{}'.format(controller_name, model_name), loop)
+ '{}:{}'.format(controller_name, model_name), loop, max_frame_size)
@classmethod
- async def connect_current_controller(cls, loop=None):
+ async def connect_current_controller(cls, loop=None, max_frame_size=None):
"""Connect to the currently active controller.
"""
if not controller_name:
raise JujuConnectionError('No current controller')
- return await cls.connect_controller(controller_name, loop)
+ return await cls.connect_controller(controller_name, loop,
+ max_frame_size)
@classmethod
- async def connect_controller(cls, controller_name, loop=None):
+ async def connect_controller(cls, controller_name, loop=None,
+ max_frame_size=None):
"""Connect to a controller by name.
"""
macaroons = get_macaroons(controller_name) if not password else None
return await cls.connect(
- endpoint, None, username, password, cacert, macaroons, loop)
+ endpoint, None, username, password, cacert, macaroons, loop,
+ max_frame_size)
@classmethod
- async def connect_model(cls, model, loop=None):
+ async def connect_model(cls, model, loop=None, max_frame_size=None):
"""Connect to a model by name.
:param str model: [<controller>:]<model>
macaroons = get_macaroons(controller_name) if not password else None
return await cls.connect(
- endpoint, model_uuid, username, password, cacert, macaroons, loop)
+ endpoint, model_uuid, username, password, cacert, macaroons, loop,
+ max_frame_size)
def build_facades(self, facades):
self.facades.clear()
class Controller(object):
- def __init__(self, loop=None):
+ def __init__(self, loop=None,
+ max_frame_size=connection.Connection.DEFAULT_FRAME_SIZE):
"""Instantiate a new Controller.
One of the connect_* methods will need to be called before this
"""
self.loop = loop or asyncio.get_event_loop()
+ self.max_frame_size = None
self.connection = None
self.controller_name = None
"""
self.connection = await connection.Connection.connect(
- endpoint, None, username, password, cacert, macaroons)
+ endpoint, None, username, password, cacert, macaroons,
+ max_frame_size=self.max_frame_size)
async def connect_current(self):
"""Connect to the current Juju controller.
"""
self.connection = (
- await connection.Connection.connect_current_controller())
+ await connection.Connection.connect_current_controller(
+ max_frame_size=self.max_frame_size))
async def connect_controller(self, controller_name):
"""Connect to a Juju controller by name.
"""
self.connection = (
- await connection.Connection.connect_controller(controller_name))
+ await connection.Connection.connect_controller(
+ controller_name, max_frame_size=self.max_frame_size))
self.controller_name = controller_name
async def disconnect(self):
self.connection)
return await controller_facade.AllModels()
-
def get_payloads(self, *patterns):
"""Return list of known payloads.
client_facade = client.UserManagerFacade.from_connection(
self.connection)
user = tag.user(username)
- return await client_facade.UserInfo([client.Entity(user)], include_disabled)
+ return await client_facade.UserInfo([client.Entity(user)],
+ include_disabled)
async def grant(self, username, acl='login'):
"""Set access level of the given user on the controller
"""
The main API for interacting with a Juju model.
"""
- def __init__(self, loop=None):
+ def __init__(self, loop=None,
+ max_frame_size=connection.Connection.DEFAULT_FRAME_SIZE):
"""Instantiate a new connected Model.
:param loop: an asyncio event loop
+ :param max_frame_size: See
+ `juju.client.connection.Connection.MAX_FRAME_SIZE`
"""
self.loop = loop or asyncio.get_event_loop()
+ self.max_frame_size = max_frame_size
self.connection = None
self.observers = weakref.WeakValueDictionary()
self.state = ModelState(self)
"""
if 'loop' not in kw:
kw['loop'] = self.loop
+ if 'max_frame_size' not in kw:
+ kw['max_frame_size'] = self.max_frame_size
self.connection = await connection.Connection.connect(*args, **kw)
await self._after_connect()
"""
self.connection = await connection.Connection.connect_current(
- self.loop)
+ self.loop, max_frame_size=self.max_frame_size)
await self._after_connect()
async def connect_model(self, model_name):
:param model_name: Format [controller:][user/]model
"""
- self.connection = await connection.Connection.connect_model(model_name,
- self.loop)
+ self.connection = await connection.Connection.connect_model(
+ model_name, self.loop, self.max_frame_size)
await self._after_connect()
async def _after_connect(self):