pass
+class OnboardPkgDcError(OnboardPkgError):
+ pass
+
+
class OnboardPkgAcctError(OnboardPkgError):
pass
self._log = log
self._args = args
+ self._project = args.project
+
self._pkgs = None
self._service_name = None
self._nsd_id = None
self._dc = None
- self._account = None
+ self._ro = None
self._ip = args.so_ip
+ self._api_server_ip = "localhost"
self._uport = args.upload_port
+ self._onboard_port = args.onboard_port
+ self._rport = args.restconf_port
+ self._user = args.restconf_user
+ self._password = args.restconf_password
+ self._onboard_url = "curl -k --user \"{user}:{passwd}\" \"https://{ip}:{port}/composer/upload?api_server=https://{api_server_ip}&upload_server=https://{ip}\"". \
+ format(ip=self._ip,
+ port=self._onboard_port,
+ user=self._user,
+ passwd=self._password,
+ api_server_ip=self._api_server_ip)
+
self._upload_url = "curl -k https://{ip}:{port}/api/upload". \
format(ip=self._ip,
port=self._uport)
- self._rport = args.restconf_port
- self._user = args.restconf_user
- self._password = args.restconf_password
self._headers = '-H "accept: application/json"' + \
' -H "content-type: application/json"'
- self._conf_url = "curl -k {header} --user \"{user}:{passwd}\" https://{ip}:{port}/api/config". \
+
+ self._conf_url = "curl -k {header} --user \"{user}:{passwd}\" https://{ip}:{port}/api/config/project/{project}". \
format(header=self._headers,
user=self._user,
passwd=self._password,
ip=self._ip,
- port=self._rport)
+ port=self._rport,
+ project=self._project)
+
+ self._oper_url = "curl -k {header} --user \"{user}:{passwd}\" https://{ip}:{port}/api/operational/project/{project}". \
+ format(header=self._headers,
+ user=self._user,
+ passwd=self._password,
+ ip=self._ip,
+ port=self._rport,
+ project=self._project)
@property
def log(self):
return self._log
def validate_args(self):
+ args = self._args
if args.upload_pkg is not None:
self._pkgs = args.upload_pkg
self.log.debug("Packages to upload: {}".format(self._pkgs))
raise OnboardPkgMissingDescId("NS Descriptor ID required for instantiation")
if args.datacenter:
- try:
- uuid.UUID(args.datacenter)
- self._dc = args.datacenter
- except ValueError as e:
- raise OnboardPkgInvalidDescId("Invalid UUID for datacenter: {}".
- format(args.datacenter))
-
- elif args.vim_account:
- self._account = args.vim_account
-
- else:
- raise OnboardPkgMissingAcct("Datacenter or VIM account required for instantiation")
+ self._dc = args.datacenter
+ if args.resource_orchestrator:
+ self._ro = args.resource_orchestrator
+
self._service_name = args.instantiate
self._nsd_id = args.nsd_id
self.log.debug("Instantiate NSD {} as {} on {}".format(self._nsd_id,
self._service_name,
- self._account))
+ self._dc))
- if (self._pkgs is None) and (self._nsd_id is None):
- raise OnboardPkgInputError("Need to specify either upload-pkg or instantiate options")
+ if (self._pkgs is None) and (self._nsd_id is None) and (not args.list_nsds):
+ raise OnboardPkgInputError("Need to specify either upload-pkg or instantiate or list options")
# Validate the port numbers are correct
def valid_port(port):
def _exec_cmd(self, cmd):
self.log.debug("Execute command: {}".format(cmd))
- proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, shell=True)
+ proc = subprocess.Popen(cmd, stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE, shell=True)
(output, err) = proc.communicate()
rc = proc.returncode
- self.log.debug("Command exec status: {}, {}, {}".format(rc, output, err))
+ self.log.debug("Command exec status: {}\nSTDOUT: {}\nSTDERR: {}".
+ format(rc, output, err))
if rc != 0:
raise OnboardPkgCmdError("Command {} failed ({}): {}".
format(cmd, rc, err))
self.log.debug("Check connectivity to SO at {}:{}, with credentials {}:{}".
format(self._ip, self._rport, self._user, self._password))
- rest_url = self._conf_url+"/resource-orchestrator"
+ rest_url = self._conf_url+"/ro-account"
try:
output = self._exec_cmd(rest_url)
self.log.debug("Output of restconf validation: {}".
def _upload_package(self, pkg):
- upload_cmd = "{url} -F \"descriptor=@{pkg}\" ". \
- format(url=self._upload_url,
+ upload_cmd = "{url} -F \"package=@{pkg}\" ". \
+ format(url=self._onboard_url,
pkg=pkg)
self.log.debug("Upload pkg {} cmd: {}".format(pkg, upload_cmd))
self.log.debug("No NSD ID provided for instantiation")
return
- # TODO: Add check to see if datacenter is valid
-
- # Check cloud account is valid, if provided
- if self._account:
- acct_url = "{url}/cloud/account/{acct}". \
- format(url=self._conf_url, acct=self._account)
- output = self._exec_cmd(acct_url)
- if (output is None) or (len(output) == 0):
- # Account not found
- raise OnboardPkgAcctError("VIM/Cloud account {} provided is not valid".
- format(self._account))
-
# Check id NSD ID is valid
nsd_url = "{url}/nsd-catalog/nsd/{nsd_id}". \
format(url=self._conf_url, nsd_id=self._nsd_id)
format(self._nsd_id,
js['error']))
- nsd = js['nsd:nsd']
+ try:
+ nsd = js['project-nsd:nsd']
+ except KeyError as e:
+ raise OnboardPkgNsdError("NSD ID {} provided is not valid".
+ format(self._nsd_id))
+
self.log.debug("NSD to instantiate: {}".format(nsd))
# Generate a UUID for NS
'name': self._service_name,
"nsd": nsd,}
if self._dc:
- nsr['om-datacenter'] = self._dc
- else:
- nsr['cloud-account'] = self._account
+ nsr['datacenter'] = self._dc
+
+ if self._ro:
+ nsr['resource-orchestrator'] = self._ro
data = {'nsr': [nsr]}
msg = "Error instantiating NS as {} with NSD {}: ". \
format(self._service_name, self._nsd_id,
reply["rpc-error"])
- self.log.error(msg)
+ # self.log.error(msg)
raise OnboardPkgInstError(msg)
self.log.info("Successfully initiated instantiation of NS as {} ({})".
format(self._service_name, ns_id))
+ def list_nsds(self):
+ if self._args.list_nsds:
+ self.log.debug("Check NSDS at {}:{}, with credentials {}:{}".
+ format(self._ip, self._rport, self._user, self._password))
+
+ rest_url = self._conf_url+"/nsd-catalog/nsd"
+ try:
+ output = self._exec_cmd(rest_url)
+ self.log.debug("Output of NSD list: {}".
+ format(output))
+ if output:
+ js = json.loads(output)
+ if "error" in js:
+ raise OnboardPkgRcConnError("SO Restconf connect error: {}".
+ format(js["error"]))
+ else:
+ print("No NSDs found on SO")
+ return
+
+ self.log.debug("NSD list: {}".format(js))
+ print('List of NSDs on SO:\nName\tID')
+ for nsd in js['project-nsd:nsd']:
+ print('{}\t{}'.format(nsd['name'], nsd['id']))
+
+ except OnboardPkgCmdError as e:
+ self.log.error("SO restconf connect failed: {}".format(e))
+ raise OnboardPkgRcConnError("SO Restconf connect error: {}".
+ format(e))
+
def process(self):
- self.validate_args()
+ try:
+ self.validate_args()
+ except Exception as e:
+ if args.verbose:
+ log.exception(e)
+
+ print("\nERROR:", e)
+ print("\n")
+ parser.print_help()
+ sys.exit(2)
+
self.validate_connectivity()
self.upload_packages()
self.instantiate()
+ self.list_nsds()
if __name__ == "__main__":
help="Descriptor packages to upload. " + \
"If multiple descriptors are provided, they are uploaded in the same sequence.")
+ parser.add_argument("-l", "--list-nsds", action='store_true',
+ help="List available network service descriptors")
+
parser.add_argument("-i", "--instantiate",
help="Instantiate a network service with the name")
parser.add_argument("-d", "--nsd-id",
help="Network descriptor ID to instantiate")
parser.add_argument("-D", "--datacenter",
help="OpenMano datacenter to instantiate on")
- parser.add_argument("-c", "--vim-account",
- help="Cloud/VIM account to instantiate on")
+ parser.add_argument("-r", "--resource-orchestrator",
+ help="RO account to instantiate on")
+ parser.add_argument("--project", default='default',
+ help="Project to use, default 'default'")
+ parser.add_argument("-o", "--onboard-port", default=8443, type=int,
+ help="Onboarding port number - node port number, default 8443")
parser.add_argument("-p", "--upload-port", default=4567, type=int,
help="Upload port number, default 4567")
- parser.add_argument("-P", "--restconf-port", default=8888, type=int,
- help="RESTconf port number, default 8888")
+ parser.add_argument("-P", "--restconf-port", default=8008, type=int,
+ help="RESTconf port number, default 8008")
parser.add_argument("--restconf-user", default='admin',
help="RESTconf user name, default admin")
parser.add_argument("--restconf-password", default='admin',
fmt = logging.Formatter(
'%(asctime)-23s %(levelname)-5s (%(name)s@%(process)d:' \
'%(filename)s:%(lineno)d) - %(message)s')
- stderr_handler = logging.StreamHandler(stream=sys.stderr)
- stderr_handler.setFormatter(fmt)
- logging.basicConfig(level=logging.INFO)
log = logging.getLogger('onboard-pkg')
- log.addHandler(stderr_handler)
+ log.setLevel(logging.INFO)
if args.verbose:
log.setLevel(logging.DEBUG)
+ ch = logging.StreamHandler()
+ ch.setLevel(logging.DEBUG)
+ ch.setFormatter(fmt)
+ log.addHandler(ch)
log.debug("Input arguments: {}".format(args))
- ob = OnboardPackage(log, args)
- ob.process()
+ try:
+ ob = OnboardPackage(log, args)
+ ob.process()
+ except Exception as e:
+ if args.verbose:
+ log.exception(e)
+
+ print("\nERROR:", e)
+ sys.exit(1)
+