# Copyright 2023 Canonical Ltd.
# Licensed under the Apache V2, see LICENCE file for details.
#
# This module allows us to parse a machine placement directive into a
# Placement object suitable for passing through the websocket API.
#
# Once https://bugs.launchpad.net/juju/+bug/1645480 is addressed, this
# module should be deprecated.
#
from .client import client
MACHINE_SCOPE = "#"
[docs]def parse(directive):
"""
Given a string in the format `scope:directive`, or simply `scope`
or `directive`, return a Placement object suitable for passing
back over the websocket API.
"""
if not directive:
# Handle null case
return None
if isinstance(directive, (list, tuple)):
results = []
for d in directive:
results.extend(parse(d))
return results
if isinstance(directive, (dict, client.Placement)):
# We've been handed something that we can simply hand back to
# the api. (Forwards compatibility)
return [directive]
# Juju 2.0 can't handle lxc containers.
directive = directive.replace('lxc', 'lxd')
if ":" in directive:
# Planner has given us a scope and directive in string form
scope, directive = directive.split(":")
return [client.Placement(scope=scope, directive=directive)]
if directive.isdigit():
# Planner has given us a machine id (we rely on juju core to
# verify its validity.)
return [client.Placement(scope=MACHINE_SCOPE, directive=directive)]
if "/" in directive:
# e.g. "0/lxd/0"
# https://github.com/juju/juju/blob/master/instance/placement_test.go#L29
return [
client.Placement(scope=MACHINE_SCOPE, directive=directive),
]
# Planner has probably given us a container type. Leave it up to
# juju core to verify that it is valid.
return [client.Placement(scope=directive)]