+ async def CreateNetworkService(self, ns_uuid):
+ """Create a new Juju model for the Network Service.
+
+ Creates a new Model in the Juju Controller.
+
+ :param str ns_uuid: A unique id representing an instaance of a
+ Network Service.
+
+ :returns: True if the model was created. Raises JujuError on failure.
+ """
+ if not self.authenticated:
+ await self.login()
+
+ models = await self.controller.list_models()
+ if ns_uuid not in models:
+ # Get the new model
+ await self.get_model(ns_uuid)
+
+ return True
+
+ async def DestroyNetworkService(self, ns_uuid):
+ """Destroy a Network Service.
+
+ Destroy the Network Service and any deployed charms.
+
+ :param ns_uuid The unique id of the Network Service
+
+ :returns: True if the model was created. Raises JujuError on failure.
+ """
+
+ # Do not delete the default model. The default model was used by all
+ # Network Services, prior to the implementation of a model per NS.
+ if ns_uuid.lower() == "default":
+ return False
+
+ if not self.authenticated:
+ await self.login()
+
+ models = await self.controller.list_models()
+ if ns_uuid in models:
+ model = await self.controller.get_model(ns_uuid)
+
+ for application in model.applications:
+ app = model.applications[application]
+
+ await self.RemoveCharms(ns_uuid, application)
+
+ self.log.debug("Unsubscribing Watcher for {}".format(application))
+ await self.Unsubscribe(ns_uuid, application)
+
+ self.log.debug("Waiting for application to terminate")
+ timeout = 30
+ try:
+ await model.block_until(
+ lambda: all(
+ unit.workload_status in ["terminated"] for unit in app.units
+ ),
+ timeout=timeout,
+ )
+ except Exception:
+ self.log.debug(
+ "Timed out waiting for {} to terminate.".format(application)
+ )
+
+ for machine in model.machines:
+ try:
+ self.log.debug("Destroying machine {}".format(machine))
+ await model.machines[machine].destroy(force=True)
+ except JujuAPIError as e:
+ if "does not exist" in str(e):
+ # Our cached model may be stale, because the machine
+ # has already been removed. It's safe to continue.
+ continue
+ else:
+ self.log.debug("Caught exception: {}".format(e))
+ raise e
+
+ # Disconnect from the Model
+ if ns_uuid in self.models:
+ self.log.debug("Disconnecting model {}".format(ns_uuid))
+ # await self.disconnect_model(self.models[ns_uuid])
+ await self.disconnect_model(ns_uuid)
+
+ try:
+ self.log.debug("Destroying model {}".format(ns_uuid))
+ await self.controller.destroy_models(ns_uuid)
+ except JujuError:
+ raise NetworkServiceDoesNotExist(
+ "The Network Service '{}' does not exist".format(ns_uuid)
+ )
+
+ return True