Exemplo n.º 1
0
    def _update_k8s_info(self,
                         cloud_owner,
                         cloud_region_id,
                         viminfo,
                         session=None):
        try:
            cloud_extra_info = viminfo.get("cloud_extra_info_json", {})

            # check if a k8s platform
            if not VimDriverUtils.check_k8s_cluster(viminfo):
                self._logger.info("%s, %s is not a k8s platform" %
                                  (cloud_owner, cloud_region_id))
                return

            # check if user token provided to access k8s platform
            k8s_apitoken = cloud_extra_info.get("k8s-apitoken")
            k8s_apiserver = cloud_extra_info.get("k8s-apiserver")
            if not k8s_apitoken or not k8s_apiserver:
                self._logger.warn("k8s-apitoken or k8s-apiserver is not provided,"\
                    "k8s connectivity must be provisioned in other ways")
                return

            # now create kube config with following template
            kubecfgdata = {
                "apiVersion":
                "v1",
                "clusters": [{
                    "cluster": {
                        "insecure-skip-tls-verify": True,
                        "server": k8s_apiserver
                    },
                    "name": "wrcpcluster"
                }],
                "contexts": [{
                    "context": {
                        "cluster": "wrcpcluster",
                        "namespace": "default",
                        "user": "******"
                    },
                    "name": "wrcpcluster-admin"
                }],
                "current-context":
                "wrcpcluster-admin",
                "kind":
                "Config",
                "preferences": {},
                "users": [{
                    "name": "admin-user",
                    "user": {
                        "token": k8s_apitoken
                    }
                }]
            }

            kubecfgfilepath = "/tmp/k8sconfig_%s_%s" % (cloud_owner,
                                                        cloud_region_id)

            # encoding = utf-8 by default
            with open(kubecfgfilepath, "w") as kubecfgfile:
                yaml.dump(kubecfgdata,
                          kubecfgfile,
                          Dumper=yaml.RoundTripDumper)

            # now create connectivity to multicloud-k8s
            multicloudK8sUrl = "%s://%s:%s/api/multicloud-k8s/v1" % (
                settings.MSB_SERVICE_PROTOCOL, settings.MSB_SERVICE_ADDR,
                settings.MSB_SERVICE_PORT)
            auth_api_url = "/v1/connectivity-info"

            metadata1 = {
                "cloud-owner": cloud_owner,
                "cloud-region": cloud_region_id,
                "other-connectivity-list": {}
            }

            with open(kubecfgfilepath, "rb") as kubecfgfile:
                files = {
                    'metadata': (None, json.dumps(metadata1)),
                    'file': kubecfgfile
                }

                resp = requests.post(multicloudK8sUrl + auth_api_url,
                                     files=files,
                                     verify=False)
                if resp.status_code == 201:
                    self._logger.info(
                        "create k8sconnectivity for %s, %s, succeeds: %s" %
                        (cloud_owner, cloud_region_id, resp.content))
                else:
                    self._logger.warn(
                        "create k8sconnectivity for %s, %s, fails:%s" %
                        (cloud_owner, cloud_region_id, resp.content))
                #print(resp.content, resp.status_code)

        except HttpError as e:
            self._logger.error("HttpError: status:%s, response:%s" %
                               (e.http_status, e.response.json()))
            return []
        except Exception:
            self._logger.error(traceback.format_exc())
            return []
Exemplo n.º 2
0
    def delete(self, request, vimid="", workloadid=""):
        self._logger.info("vimid, workload id: %s, %s" % (vimid, workloadid))
        self._logger.debug("META: %s" % request.META)

        resp_template = {
            "template_type": "HEAT",
            "workload_id": workloadid,
            "workload_status": "DELETE_FAILED",
            "workload_status_reason": "Exception occurs"
        }
        status_code = status.HTTP_500_INTERNAL_SERVER_ERROR

        # check if target to k8s
        viminfo = VimDriverUtils.get_vim_info(vimid)
        if VimDriverUtils.check_k8s_cluster(viminfo):
            try:
                # wrap call to multicloud-k8s
                return k8s_infra_workload_helper.InfraWorkloadHelper.workload_delete(
                    self, vimid, workloadid, request)
            except Exception as e:
                errmsg = str(e)
                self._logger.error(errmsg)
                resp_template["workload_status_reason"] = errmsg
                return Response(data=resp_template,
                                status=status.HTTP_500_INTERNAL_SERVER_ERROR)

        # otherwise, target to openstack
        # Get the specified tenant id
        specified_project_idorname = request.META.get("Project", None)

        try:
            if workloadid == "":
                resp_template["workload_status_reason"] =\
                    "workload id is not found in API url"
                return Response(data=resp_template,
                                status=status.HTTP_400_BAD_REQUEST)

            # remove the stack object from vim
            super(InfraWorkload, self).delete(request, vimid, workloadid)

            # backlog for a post to heatbridge delete
            worker_self = openstack_infra_workload_helper.InfraWorkloadHelper(
                settings.MULTICLOUD_API_V1_PREFIX, settings.AAI_BASE_URL)
            backlog_item = {
                "id":
                workloadid,
                "worker":
                worker_self.workload_delete,
                "payload":
                (vimid, workloadid, request.data, specified_project_idorname),
                "repeat":
                0,  # one time job
                # format of status: retcode:0 is ok, otherwise error code from http status, Status ENUM, Message
                "status":
                (0, "DELETE_IN_PROGRESS", "backlog for delete the workload %s "
                 "is on progress" % workloadid)
            }
            gInfraWorkloadThread.add(backlog_item)
            if 0 == gInfraWorkloadThread.state():
                gInfraWorkloadThread.start()

            # now query the progress
            backlog_item = gInfraWorkloadThread.get(workloadid)
            if not backlog_item:
                # backlog item not found
                resp_template["workload_status_reason"] = \
                    "backlog to remove the "\
                    "workload %s is not found" % workloadid

                return Response(data=resp_template,
                                status=status.HTTP_500_INTERNAL_SERVER_ERROR)
            else:
                progress = backlog_item.get(
                    "status", (13, "DELETE_FAILED",
                               "Unexpected:status not found in backlog item"))
                try:
                    progress_code = progress[0]
                    progress_status = progress[1]
                    progress_msg = progress[2]
                    # if gInfraWorkloadThread.expired(workloadid):
                    #     gInfraWorkloadThread.remove(workloadid)

                    resp_template["workload_status"] = progress_status
                    resp_template["workload_status_reason"] = progress_msg
                    status_code = status.HTTP_202_ACCEPTED \
                        if progress_code == 0 else progress_code
                except Exception as e:
                    resp_template["workload_status_reason"] = progress
                return Response(data=resp_template, status=status_code)
        except Exception as e:
            self._logger.error(str(e))
            resp_template["workload_status_reason"] = str(e)
            return Response(data=resp_template,
                            status=status.HTTP_500_INTERNAL_SERVER_ERROR)
Exemplo n.º 3
0
    def post(self, request, vimid="", workloadid=""):
        self._logger.info("vimid: %s, stackid:%s" % (vimid, workloadid))
        self._logger.info("data: %s" % request.data)
        self._logger.debug("META: %s" % request.META)

        resp_template = {
            "template_type": "HEAT",
            "workload_id": workloadid,
            "workload_status": "CREATE_FAILED",
            "workload_status_reason": "Exception occurs"
        }
        status_code = status.HTTP_500_INTERNAL_SERVER_ERROR

        # check if target to k8s
        viminfo = VimDriverUtils.get_vim_info(vimid)
        if VimDriverUtils.check_k8s_cluster(viminfo):
            try:
                # wrap call to multicloud-k8s
                return k8s_infra_workload_helper.InfraWorkloadHelper.workload_create(
                    self, vimid, workloadid, request)
            except Exception as e:
                errmsg = str(e)
                self._logger.error(errmsg)
                resp_template["workload_status_reason"] = errmsg
                return Response(data=resp_template,
                                status=status.HTTP_500_INTERNAL_SERVER_ERROR)

        # otherwise, target to openstack
        # Get the specified tenant id
        specified_project_idorname = request.META.get("Project", None)

        try:
            worker_self = openstack_infra_workload_helper.InfraWorkloadHelper(
                settings.MULTICLOUD_API_V1_PREFIX, settings.AAI_BASE_URL)
            if workloadid == "":
                resp_template["workload_status"] = "CREATE_FAILED"
                # post to create a new stack,
                # stack id available only after creating a stack is done
                progress_code, progress_status, progress_msg =\
                    worker_self.workload_create(vimid, request.data, specified_project_idorname)
                resp_template["workload_status"] = progress_status
                resp_template["workload_status_reason"] = progress_msg

                if progress_code == 0:
                    # update workload_id
                    stack = progress_msg
                    stackid = stack["id"]
                    resp_template["workload_id"] = stackid
                    status_code = status.HTTP_201_CREATED
                else:
                    status_code = status.HTTP_400_BAD_REQUEST

                return Response(data=resp_template, status=status_code)
                # return super(InfraWorkload, self).post(request, vimid)
            else:
                resp_template["workload_status"] = "UPDATE_FAILED"
                # a post to heatbridge
                backlog_item = {
                    "id":
                    workloadid,
                    "worker":
                    worker_self.workload_update,
                    "payload": (vimid, workloadid, request.data,
                                specified_project_idorname),
                    "repeat":
                    0,  # one time job
                    # format of status: retcode:0 is ok, otherwise error code from http status, Status ENUM, Message
                    "status": (0, "UPDATE_IN_PROGRESS",
                               "backlog to update workload %s is on progress" %
                               workloadid)
                }
                gInfraWorkloadThread.add(backlog_item)
                if 0 == gInfraWorkloadThread.state():
                    gInfraWorkloadThread.start()
                # progress = worker_self.workload_update(
                #     vimid, workloadid,
                #     request.data, specified_project_idorname)
                # now query the progress
                backlog_item = gInfraWorkloadThread.get(workloadid)
                if not backlog_item:
                    # backlog item not found
                    resp_template["workload_status_reason"] = \
                        "backlog to update workload %s " \
                        "into AAI is not found" % workloadid
                    return Response(
                        data=resp_template,
                        status=status.HTTP_500_INTERNAL_SERVER_ERROR)
                else:
                    progress = backlog_item.get(
                        "status",
                        (13, "UPDATE_FAILED",
                         "Unexpected:status not found in backlog item"))

                    try:
                        progress_code = progress[0]
                        progress_status = progress[1]
                        progress_msg = progress[2]
                        resp_template["workload_status"] = progress_status
                        resp_template["workload_status_reason"] = progress_msg

                        status_code = status.HTTP_202_ACCEPTED\
                            if progress_code == 0 else progress_code
                    except Exception as e:
                        self._logger.warn("Exception: %s" % str(e))
                        resp_template["workload_status_reason"] = progress

                    return Response(data=resp_template, status=status_code)
        except Exception as e:
            errmsg = str(e)
            self._logger.error(errmsg)
            resp_template["workload_status_reason"] = errmsg
            return Response(data=resp_template,
                            status=status.HTTP_500_INTERNAL_SERVER_ERROR)
Exemplo n.º 4
0
    def get(self, request, vimid="", workloadid=""):
        self._logger.info("vimid, workload id: %s, %s" % (vimid, workloadid))
        self._logger.debug("META: %s" % request.META)

        resp_template = {
            "template_type": "HEAT",
            "workload_id": workloadid,
            "workload_status": "GET_FAILED",
            "workload_status_reason": "Exception occurs"
        }
        status_code = status.HTTP_500_INTERNAL_SERVER_ERROR

        # check if target to k8s
        viminfo = VimDriverUtils.get_vim_info(vimid)
        if VimDriverUtils.check_k8s_cluster(viminfo):
            try:
                # wrap call to multicloud-k8s
                return k8s_infra_workload_helper.InfraWorkloadHelper.workload_detail(
                    self, vimid, workloadid, request)
            except Exception as e:
                errmsg = str(e)
                self._logger.error(errmsg)
                resp_template["workload_status_reason"] = errmsg
                return Response(data=resp_template,
                                status=status.HTTP_500_INTERNAL_SERVER_ERROR)

        # Otherwise target to openstack
        #  Get the specified tenant id
        specified_project_idorname = request.META.get("Project", None)

        try:

            if workloadid == "":
                # now check the query params in case of query existing of workload
                querystr = request.META.get("QUERY_STRING", None)
                qd = QueryDict(querystr).dict() if querystr else None
                workload_query_name = qd.get("name", None) if qd else None
                workload_query_id = qd.get("id", None) if qd else None

                if not workload_query_name and not workload_query_id:
                    resp_template["workload_status_reason"] =\
                        "workload id is not found in API url"
                    return Response(data=resp_template,
                                    status=status.HTTP_400_BAD_REQUEST)
                else:
                    worker_self = openstack_infra_workload_helper.InfraWorkloadHelper(
                        settings.MULTICLOUD_API_V1_PREFIX,
                        settings.AAI_BASE_URL)

                    # now query the status of workload by name or id, id as 1st priority
                    progress_code, progress_status, progress_msg =\
                        0, "GET_FAILED", ""
                    if workload_query_id:
                        # by id
                        progress_code, progress_status, progress_msg =\
                            worker_self.workload_status(
                                vimid, stack_id=workload_query_id,
                                project_idorname=specified_project_idorname
                            )
                    else:
                        # by name or get all stacks
                        progress_code, progress_status, progress_msg =\
                            worker_self.workload_status(
                                vimid, stack_name=workload_query_name,
                                project_idorname=specified_project_idorname
                            )

                    resp_template["workload_status"] = progress_status
                    resp_template["workload_status_reason"] = progress_msg
                    status_code = status.HTTP_200_OK \
                        if progress_code == 0 else status.HTTP_500_INTERNAL_SERVER_ERROR  # progress_code

                    pass

            else:
                # now query the progress
                backlog_item = gInfraWorkloadThread.get(workloadid)
                if not backlog_item:
                    # backlog item not found, so check the stack status
                    worker_self = openstack_infra_workload_helper.InfraWorkloadHelper(
                        settings.MULTICLOUD_API_V1_PREFIX,
                        settings.AAI_BASE_URL)
                    progress_code, progress_status, progress_msg =\
                        worker_self.workload_detail(
                            vimid, stack_id=workloadid,
                            project_idorname=specified_project_idorname)

                    resp_template["workload_status"] = progress_status
                    resp_template["workload_status_reason"] = progress_msg
                    status_code = status.HTTP_200_OK\
                        if progress_code == 0 else progress_code

                else:
                    progress = backlog_item.get(
                        "status",
                        (13, "GET_FAILED",
                         "Unexpected:status not found in backlog item"))
                    try:
                        progress_code = progress[0]
                        progress_status = progress[1]
                        progress_msg = progress[2]
                        # if gInfraWorkloadThread.expired(workloadid):
                        #     gInfraWorkloadThread.remove(workloadid)
                        resp_template["workload_status"] = progress_status
                        resp_template["workload_status_reason"] = progress_msg
                        status_code = status.HTTP_200_OK\
                            if progress_code == 0 else progress_code
                    except Exception as e:
                        resp_template["workload_status_reason"] = progress

            return Response(data=resp_template, status=status_code)

        except Exception as e:
            self._logger.error(str(e))
            resp_template["workload_status_reason"] = str(e)
            return Response(data=resp_template,
                            status=status.HTTP_500_INTERNAL_SERVER_ERROR)