X-Git-Url: https://osm.etsi.org/gitweb/?p=osm%2FN2VC.git;a=blobdiff_plain;f=n2vc%2Fvnf.py;h=9f0440538377d8c0cf0d918d3e1af6c19b13e09b;hp=8064cb3489680501d918c3a8dd5dbcecebc87e04;hb=1ddca81e7e1863b0a7d45d1b9b9d5cabccd4e628;hpb=fc511ed0e2f3bbbdc0ccaa6b0d6ae7cc57b029f9 diff --git a/n2vc/vnf.py b/n2vc/vnf.py index 8064cb3..9f04405 100644 --- a/n2vc/vnf.py +++ b/n2vc/vnf.py @@ -3,7 +3,9 @@ import logging import os import os.path import re +import shlex import ssl +import subprocess import sys # import time @@ -333,14 +335,22 @@ class N2VC: ######################################################## to = "" if machine_spec.keys(): - # TODO: This needs to be tested. - # if all(k in machine_spec for k in ['hostname', 'username']): - # # Enlist the existing machine in Juju - # machine = await self.model.add_machine(spec='ssh:%@%'.format( - # specs['host'], - # specs['user'], - # )) - # to = machine.id + if all(k in machine_spec for k in ['hostname', 'username']): + # Get the path to the previously generated ssh private key. + # Machines we're manually provisioned must have N2VC's public + # key injected, so if we don't have a keypair, raise an error. + private_key_path = "" + + # Enlist the existing machine in Juju + machine = await self.model.add_machine( + spec='ssh:{}@{}:{}'.format( + specs['host'], + specs['user'], + private_key_path, + ) + ) + # Set the machine id that the deploy below will use. + to = machine.id pass ####################################### @@ -351,9 +361,6 @@ class N2VC: if 'rw_mgmt_ip' in params: rw_mgmt_ip = params['rw_mgmt_ip'] - # initial_config = {} - # self.log.debug(type(params)) - # self.log.debug("Params: {}".format(params)) if 'initial-config-primitive' not in params: params['initial-config-primitive'] = {} @@ -382,8 +389,8 @@ class N2VC: series='xenial', # Apply the initial 'config' primitive during deployment config=initial_config, - # TBD: Where to deploy the charm to. - to=None, + # Where to deploy the charm to. + to=to, ) # ####################################### @@ -487,6 +494,77 @@ class N2VC: return results + # async def ProvisionMachine(self, model_name, hostname, username): + # """Provision machine for usage with Juju. + # + # Provisions a previously instantiated machine for use with Juju. + # """ + # try: + # if not self.authenticated: + # await self.login() + # + # # FIXME: This is hard-coded until model-per-ns is added + # model_name = 'default' + # + # model = await self.get_model(model_name) + # model.add_machine(spec={}) + # + # machine = await model.add_machine(spec='ssh:{}@{}:{}'.format( + # "ubuntu", + # host['address'], + # private_key_path, + # )) + # return machine.id + # + # except Exception as e: + # self.log.debug( + # "Caught exception while getting primitive status: {}".format(e) + # ) + # raise N2VCPrimitiveExecutionFailed(e) + + def GetPrivateKeyPath(self): + homedir = os.environ['HOME'] + sshdir = "{}/.ssh".format(homedir) + private_key_path = "{}/id_n2vc_rsa".format(sshdir) + return private_key_path + + async def GetPublicKey(self): + """Get the N2VC SSH public key.abs + + Returns the SSH public key, to be injected into virtual machines to + be managed by the VCA. + + The first time this is run, a ssh keypair will be created. The public + key is injected into a VM so that we can provision the machine with + Juju, after which Juju will communicate with the VM directly via the + juju agent. + """ + public_key = "" + + # Find the path to where we expect our key to live. + homedir = os.environ['HOME'] + sshdir = "{}/.ssh".format(homedir) + if not os.path.exists(sshdir): + os.mkdir(sshdir) + + private_key_path = "{}/id_n2vc_rsa".format(sshdir) + public_key_path = "{}.pub".format(private_key_path) + + # If we don't have a key generated, generate it. + if not os.path.exists(private_key_path): + cmd = "ssh-keygen -t {} -b {} -N '' -f {}".format( + "rsa", + "4096", + private_key_path + ) + subprocess.check_output(shlex.split(cmd)) + + # Read the public key + with open(public_key_path, "r") as f: + public_key = f.readline() + + return public_key + async def ExecuteInitialPrimitives(self, model_name, application_name, params, callback=None, *callback_args): """Execute multiple primitives. @@ -650,6 +728,13 @@ class N2VC: return metrics + async def HasApplication(self, model_name, application_name): + model = await self.get_model(model_name) + app = await self.get_application(model, application_name) + if app: + return True + return False + # Non-public methods async def add_relation(self, a, b, via=None): """