+# These functions are written to use the JujuApi class from juju_api.py, a
+# drop-in copy of the one used in OSM today. This will make it easier to extend
+# functionality in the LCM as it's added to the Juju API
+
+
+def GetJujuApi(loop):
+ # Quiet logging from the websocket library. If you want to see
+ # everything sent over the wire, set this to DEBUG.
+ logging.basicConfig(level=logging.DEBUG)
+
+ ws_logger = logging.getLogger('websockets.protocol')
+ ws_logger.setLevel(logging.INFO)
+
+ api = JujuApi(server=vca_account['ip'],
+ port=vca_account['port'],
+ user=vca_account['user'],
+ secret=vca_account['secret'],
+ loop=loop,
+ log=ws_logger,
+ model_name='default'
+ )
+ return api
+
+
+def get_vnf_unique_name(nsr_name, vnfr_name, member_vnf_index):
+ """Get the unique VNF name.
+ Charm names accepts only a to z and non-consecutive - characters."""
+ name = "{}-{}-{}".format(nsr_name, vnfr_name, member_vnf_index)
+ new_name = ''
+ for c in name:
+ if c.isdigit():
+ c = chr(97 + int(c))
+ elif not c.isalpha():
+ c = "-"
+ new_name += c
+ return re.sub('\-+', '-', new_name.lower())
+
+
+async def DeployApplication(loop, application_name, charm_path, config):
+ """
+ Deploy a charm.
+
+ Deploy a VNF configuration charm from a local directory.
+ :param object loop: The event loop
+ :param str application_name: The unique name of this application.
+ :param str charm_path: The path to the charm.
+
+ :Example:
+
+ DeployApplication(loop, ".cache/ping_vnf/charm/pingpong", "ping_vnf")
+ """
+
+ api = GetJujuApi(loop)
+
+ await api.login()
+ if api.authenticated:
+ charm = os.path.basename(charm_path)
+
+ await api.deploy_application(charm,
+ name=application_name,
+ path=charm_path,
+ )
+ await api.apply_config(config, application_name)
+
+ # Wait for the application to fully deploy. This will block until the
+ # agent is in an idle state, and the charm's workload is either
+ # 'active' or 'unknown', meaning it's ready but the author did not
+ # explicitly set a workload state.
+ # print("Waiting for application '{}' to deploy...".format(charm))
+ while (True):
+ # Deploy the charm and wait, periodically checking its status
+ await api.wait_for_application(charm, 30)
+
+ error = await api.is_application_error(charm)
+ if error:
+ print("This application is in an error state.")
+ break
+
+ blocked = await api.is_application_blocked(charm)
+ if blocked:
+ print("This application is blocked.")
+ break
+
+ # An extra check to see if the charm is ready
+ up = await api.is_application_up(charm)
+ # print("Application is {}".format("up" if up else "down"))
+
+ print("Application {} is deployed".format(args.application))
+ await api.logout()
+
+
+async def RemoveApplication(loop, application_name):
+ """
+ Remove an application from the Juju Controller
+
+ Removed the named application and it's charm from the Juju controller.
+
+ :param object loop: The event loop.
+ :param str application_name: The unique name of the application.
+
+ :Example:
+
+ RemoveApplication(loop, "ping_vnf")
+ RemoveApplication(loop, "pong_vnf")
+ """
+ api = GetJujuApi(loop)
+
+ await api.login()
+ if api.authenticated:
+ print("Removing application {}".format(application_name))
+ await api.remove_application(application_name)
+ await api.logout()
+