Bug 219 : Improve error handling
[osm/SO.git] / rwlaunchpad / plugins / rwlaunchpadtasklet / scripts / onboard_pkg
old mode 100644 (file)
new mode 100755 (executable)
index b616ccf..ba82e7e
@@ -72,6 +72,10 @@ class OnboardPkgRcConnError(OnboardPkgError):
     pass
 
 
+class OnboardPkgDcError(OnboardPkgError):
+    pass
+
+
 class OnboardPkgAcctError(OnboardPkgError):
     pass
 
@@ -104,15 +108,23 @@ class OnboardPackage:
         self._account = 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". \
@@ -121,6 +133,12 @@ class OnboardPackage:
                               passwd=self._password,
                               ip=self._ip,
                               port=self._rport)
+        self._oper_url = "curl -k {header} --user \"{user}:{passwd}\" https://{ip}:{port}/api/operational". \
+                       format(header=self._headers,
+                              user=self._user,
+                              passwd=self._password,
+                              ip=self._ip,
+                              port=self._rport)
 
     @property
     def log(self):
@@ -180,10 +198,12 @@ class OnboardPackage:
 
     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))
@@ -224,8 +244,8 @@ class OnboardPackage:
 
 
     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))
 
@@ -263,7 +283,31 @@ class OnboardPackage:
             self.log.debug("No NSD ID provided for instantiation")
             return
 
-        # TODO: Add check to see if datacenter is valid
+        # Check to see if datacenter is valid
+        if self._dc:
+            dc_url = "{url}/datacenters". format(url=self._oper_url)
+            output = self._exec_cmd(dc_url)
+            if (output is None) or (len(output) == 0):
+                # Account not found
+                raise OnboardPkgDcError("Datacenter {} provided is not valid".
+                                        format(self._dc))
+            found = False
+            js = json.loads(output)
+            if "ro-accounts" in js["rw-launchpad:datacenters"]:
+                for ro in js["rw-launchpad:datacenters"]["ro-accounts"]:
+                    if "datacenters" in ro:
+                        for dc in ro["datacenters"]:
+                            if dc["uuid"] == self._dc:
+                                self.log.debug("Found datacenter {}".format(dc))
+                                found = True
+                                break
+                    if found:
+                        break
+
+            if found is False:
+                raise OnboardPkgDcError("Datacenter {} provided is not valid".
+                                        format(self._dc))
+
 
         # Check cloud account is valid, if provided
         if self._account:
@@ -331,14 +375,24 @@ class OnboardPackage:
                 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 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()
@@ -362,10 +416,12 @@ if __name__ == "__main__":
     parser.add_argument("-c", "--vim-account",
                         help="Cloud/VIM account to instantiate on")
 
+    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',
@@ -379,15 +435,24 @@ if __name__ == "__main__":
     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)
+