X-Git-Url: https://osm.etsi.org/gitweb/?p=osm%2FN2VC.git;a=blobdiff_plain;f=n2vc%2Fvnf.py;h=38a9d154482d64925772c25836f7c8b8832072f4;hp=6e4aaf37e8bd013663eb4d03c6dbe766408cdb3f;hb=b2a07f566be558a8b59b8b5dedfe8da5ae1b0132;hpb=6d84dbd8746388114361e09300697da471de20ca diff --git a/n2vc/vnf.py b/n2vc/vnf.py index 6e4aaf3..38a9d15 100644 --- a/n2vc/vnf.py +++ b/n2vc/vnf.py @@ -57,13 +57,12 @@ logging.getLogger('juju.machine').setLevel(logging.WARN) class VCAMonitor(ModelObserver): """Monitor state changes within the Juju Model.""" log = None - ns_name = None - applications = {} def __init__(self, ns_name): self.log = logging.getLogger(__name__) self.ns_name = ns_name + self.applications = {} def AddApplication(self, application_name, callback, *callback_args): if application_name not in self.applications: @@ -148,22 +147,34 @@ class N2VC: secret=None, artifacts=None, loop=None, + juju_public_key=None, + ca_cert=None, ): """Initialize N2VC - - :param vcaconfig dict A dictionary containing the VCA configuration - - :param artifacts str The directory where charms required by a vnfd are + :param log obj: The logging object to log to + :param server str: The IP Address or Hostname of the Juju controller + :param port int: The port of the Juju Controller + :param user str: The Juju username to authenticate with + :param secret str: The Juju password to authenticate with + :param artifacts str: The directory where charms required by a vnfd are stored. + :param loop obj: The loop to use. + :param juju_public_key str: The contents of the Juju public SSH key + :param ca_cert str: The CA certificate to use to authenticate + :Example: - n2vc = N2VC(vcaconfig={ - 'secret': 'MzI3MDJhOTYxYmM0YzRjNTJiYmY1Yzdm', - 'user': 'admin', - 'ip-address': '10.44.127.137', - 'port': 17070, - 'artifacts': '/path/to/charms' - }) + client = n2vc.vnf.N2VC( + log=log, + server='10.1.1.28', + port=17070, + user='admin', + secret='admin', + artifacts='/app/storage/myvnf/charms', + loop=loop, + juju_public_key='', + ca_cert='', + ) """ # Initialize instance-level variables @@ -190,6 +201,12 @@ class N2VC: self.username = "" self.secret = "" + self.juju_public_key = juju_public_key + if juju_public_key: + self._create_juju_public_key(juju_public_key) + + self.ca_cert = ca_cert + if log: self.log = log else: @@ -222,6 +239,25 @@ class N2VC: """Close any open connections.""" yield self.logout() + def _create_juju_public_key(self, public_key): + """Recreate the Juju public key on disk. + + Certain libjuju commands expect to be run from the same machine as Juju + is bootstrapped to. This method will write the public key to disk in + that location: ~/.local/share/juju/ssh/juju_id_rsa.pub + """ + if public_key is None or len(public_key) == 0: + return + + path = "{}/.local/share/juju/ssh".format( + os.path.expanduser('~'), + ) + if not os.path.exists(path): + os.makedirs(path) + + with open('{}/juju_id_rsa.pub'.format(path), 'w') as f: + f.write(public_key) + def notify_callback(self, model_name, application_name, status, message, callback=None, *callback_args): try: @@ -769,11 +805,11 @@ class N2VC: await self.disconnect_model(self.monitors[model_name]) - # Notify the callback that this charm has been removed. self.notify_callback( model_name, application_name, "removed", + "Removing charm {}".format(application_name), callback, *callback_args, ) @@ -805,6 +841,10 @@ class N2VC: except JujuError as e: if "already exists" not in e.message: raise e + + # Create an observer for this model + await self.create_model_monitor(ns_uuid) + return True async def DestroyNetworkService(self, ns_uuid): @@ -819,7 +859,7 @@ class N2VC: # 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() is "default": + if ns_uuid.lower() == "default": return False if not self.authenticated: @@ -832,7 +872,7 @@ class N2VC: try: await self.controller.destroy_models(ns_uuid) - except JujuError as e: + except JujuError: raise NetworkServiceDoesNotExist( "The Network Service '{}' does not exist".format(ns_uuid) ) @@ -1061,10 +1101,20 @@ class N2VC: self.refcount['model'] += 1 # Create an observer for this model + await self.create_model_monitor(model_name) + + return self.models[model_name] + + async def create_model_monitor(self, model_name): + """Create a monitor for the model, if none exists.""" + if not self.authenticated: + await self.login() + + if model_name not in self.monitors: self.monitors[model_name] = VCAMonitor(model_name) self.models[model_name].add_observer(self.monitors[model_name]) - return self.models[model_name] + return True async def login(self): """Login to the Juju controller.""" @@ -1076,7 +1126,6 @@ class N2VC: self.log.debug("JujuApi: Logging into controller") - cacert = None self.controller = Controller(loop=self.loop) if self.secret: @@ -1092,7 +1141,7 @@ class N2VC: endpoint=self.endpoint, username=self.user, password=self.secret, - cacert=cacert, + cacert=self.ca_cert, ) self.refcount['controller'] += 1 else: