def put()

in source/soca/cluster_web_ui/api/v1/dcv/stop_desktop.py [0:0]


    def put(self, session_number, action):
        """
        Stop/Hibernate a DCV desktop session
        ---
        tags:
          - DCV

        parameters:
          - in: body
            name: body
            schema:
              required:
                - os
              properties:
                session_number:
                  type: string
                  description: Session Number
                action:
                  type: string
                  description: Stop/Hibernate or Terminate
                os:
                  type: string
                  description: DCV session type (Windows or Linux)

        responses:
          200:
            description: Pair of user/token is valid
          401:
            description: Invalid user/token pair
        """
        parser = reqparse.RequestParser()
        parser.add_argument("os", type=str, location='form')

        args = parser.parse_args()
        user = request.headers.get("X-SOCA-USER")
        if session_number is None:
            return errors.all_errors('CLIENT_MISSING_PARAMETER', "session_number not found in URL. Endpoint is /api/dcv/desktop/<session_number>/<action>")
        else:
            args["session_number"] = str(session_number)

        if action is None:
            return errors.all_errors('CLIENT_MISSING_PARAMETER',  "action not found in URL. Endpoint is /api/dcv/desktop/<session_number>/<action>")
        else:
            args["action"] = action

        if user is None:
            return errors.all_errors("X-SOCA-USER_MISSING")

        if args["os"] is None:
            return errors.all_errors('CLIENT_MISSING_PARAMETER', "os (str)")

        if args["os"].lower() not in ["linux", "windows"]:
            return errors.all_errors('CLIENT_MISSING_PARAMETER', "os must be linux or windows")

        if args["action"] not in ["terminate", "stop", "hibernate"]:
            return errors.all_errors('CLIENT_MISSING_PARAMETER', "action must be terminate, stop or hibernate")

        if args["os"].lower() == "linux":
            check_session = LinuxDCVSessions.query.filter_by(user=user, session_number=str(args["session_number"]), is_active=True).first()
        else:
            check_session = WindowsDCVSessions.query.filter_by(user=user, session_number=str(args["session_number"]), is_active=True).first()

        if check_session:
            instance_id = check_session.session_instance_id
            session_name = check_session.session_name

            if args["action"] == "hibernate":
                if check_session.session_state == "stopped":
                    return errors.all_errors('DCV_STOP_ERROR', f"Your instance is already stopped.")
                else:
                    # Hibernate instance
                    try:
                        client_ec2.stop_instances(InstanceIds=[instance_id], Hibernate=True, DryRun=True)
                    except ClientError as e:
                        if e.response['Error'].get('Code') == 'DryRunOperation':
                            client_ec2.stop_instances(InstanceIds=[instance_id], Hibernate=True)
                            check_session.session_state = "stopped"
                            db.session.commit()
                        else:
                            return errors.all_errors('DCV_STOP_ERROR', f"Unable to hibernate instance ({instance_id}) due to {e}")

            elif args["action"] == "stop":
                if check_session.session_state in "stopped":
                    return errors.all_errors('DCV_STOP_ERROR', f"Your desktop is already stopped.")
                # Stop Instance
                else:
                    try:
                        client_ec2.stop_instances(InstanceIds=[instance_id], DryRun=True)
                    except ClientError as e:
                        if e.response['Error'].get('Code') == 'DryRunOperation':
                            try:
                                client_ec2.stop_instances(InstanceIds=[instance_id])
                            except ClientError as err:
                                # case when someone stop an EC2 instance still initializing. This use case is not handle by the DryRun so we need
                                return errors.all_errors('DCV_STOP_ERROR',
                                                         f"Unable to stop instance, maybe the instance is not running yet. Error {err}")
                            check_session.session_state = "stopped"
                            db.session.commit()
                        else:
                            return errors.all_errors('DCV_STOP_ERROR', f"Unable to stop instance ({instance_id}) due to {e}")

            else:
                # Terminate instance
                stack_name = str(read_secretmanager.get_soca_configuration()["ClusterId"] + "-" + session_name + "-" + user)
                try:
                    client_cfn.delete_stack(StackName=stack_name)
                    check_session.is_active = False
                    check_session.deactivated_on = datetime.utcnow()
                    db.session.commit()
                    return {"success": True, "message": f"Your graphical session {session_name} is about to be terminated"}, 200
                except ClientError as e:
                    return errors.all_errors('DCV_STOP_ERROR', f"Unable to delete cloudformation stack ({stack_name}) due to {e}")
                except Exception as e:
                    return errors.all_errors('DCV_STOP_ERROR',f"Unable to update db due to {e}")
        else:
            return errors.all_errors('DCV_STOP_ERROR', f"This session does not exist or is not active")