def cs_logoff(self):
        """To logoff from CS

        :Datafile usage:
             NA
        :Arguments:
             NA
        :Returns:
            1. status(bool)= True/False
        """

        wdesc = "To logoff from CS"
        testcase_Utils.pSubStep(wdesc)
        testcase_Utils.pNote(file_Utils.getDateTime())

        status = False
        testcase_Utils.pNote("cs_logoff, cs obj-{}".format(cloud_shell),
                             "info")
        xml_resp = cloud_shell.Logoff()

        if xml_resp is not None:
            testcase_Utils.pNote(
                "\n\n *** Cloudshell LogOff successfull-%s" %
                (cloud_shell.host), "info")
            status = True
        else:
            testcase_Utils.pNote(
                "\n\n *** Cloudshell LogOff failed-%s" % (cloud_shell.host),
                "warning")

        testcase_Utils.report_substep_status(status)
        return status
    def cs_get_topo_details(self, topology_path):
        """To get the Cloudshell topology details for a given path

        :Datafile usage:
             NA
        :Arguments:
            1. topology_path(string) = Specify the full topology name. Include
               the full path from the root to the topology, separated by slashes.
               For example: FolderName/Topologies/TopologyName

        :Returns:
            1. status(bool)= True/False
        """

        wdesc = "To get the Cloudshell topology details for a given path"
        testcase_Utils.pSubStep(wdesc)
        testcase_Utils.pNote(file_Utils.getDateTime())

        status = False
        testcase_Utils.pNote("cs_get_topo_details, cs obj-{}".\
                             format(cloud_shell), "info")
        try:
            xml_resp = cloud_shell.GetTopologyDetails(topology_path)
            if xml_resp is not None:
                testcase_Utils.pNote("\n\n *** Get Topolopy \"%s\" successfull\n"\
                                     % (topology_path), "info")
                status = True
            else:
                testcase_Utils.pNote("\n\n *** Get Topolopy \"%s\" failed\n"\
                                     % (topology_path), "warning")
        except Exception as exception:
            print_exception(exception)

        testcase_Utils.report_substep_status(status)
        return status
    def connect_to_cs(self, system_name):
        """Logs in to API host using passed user credentials and domain

        :Datafile usage:
             NA
        :Arguments:
            1. system_name(string) = Name of the system from the datafile

        :Returns:
            1. status(bool)= True/False
        """

        wdesc = "Logon to CloudShell API Host"
        testcase_Utils.pSubStep(wdesc)
        testcase_Utils.pNote(file_Utils.getDateTime())

        global cloud_shell
        cloud_shell = self._create_cs_obj(system_name)
        testcase_Utils.pNote("Login, cs obj-{}".format(cloud_shell), "info")

        status = False
        if cloud_shell is not None:
            testcase_Utils.pNote("\n\n *** Login to Cloudshell System-{}"
                                 " successfull, domain-{}\n".\
                                 format(cloud_shell.host,\
                                 cloud_shell.domain), "info")
            status = True
        else:
            testcase_Utils.pNote(
                "\n\n *** Login to Cloudshell System"
                " failed\n", "warning")

        testcase_Utils.report_substep_status(status)
        return status
    def cs_create_route_in_reservation(self, system_name, reservation_name,
                                       source_resource_full_path,
                                       target_resource_full_path,
                                       override_active_routes, mapping_type,
                                       max_hops, route_alias, is_shared):
        """Creates routes between the specified source and target resources.

        :Arguments:
            1. system_name(string) = Name of the UAP system from the datafile
            2. reservation_name(string) = Specify the name of the reservation.
            3. source_resource_full_path(string) = Specify the source resource
                full path
            4. target_resource_full_path(string) = Specify the target resource
                full path
            5. mapping_type(string) = Specify bi-directional or uni-directional
               as the mapping type
            6. max_hops(integer) = The maximum number of allowed hops.
            7. route_alias(string) = Specify the route alias
            8. override_active_routes(bool) = Specify whether the new route
                can override existing routes.
            9. is_shared(bool) = Specify whether these routes are shared.
        :Returns:
            1. status(bool) = True/False
        """

        wdesc = "Create Route In Reservation in CloudShell API Host"
        testcase_Utils.pSubStep(wdesc)
        testcase_Utils.pNote(file_Utils.getDateTime())

        testcase_Utils.pNote(
            "cs_create_route_in_reservation, cs obj-{}".format(cloud_shell),
            "info")

        status = False
        cs_res_id = data_Utils.get_object_from_datarepository(
            system_name + "_" + reservation_name + "_reservationId")
        try:
            xml_resp = cloud_shell.CreateRouteInReservation(
                cs_res_id, source_resource_full_path,
                target_resource_full_path, override_active_routes,
                mapping_type, int(max_hops), route_alias, is_shared)

            if xml_resp is not None:
                testcase_Utils.pNote(
                    "\n\n *** Cloudshell Create Route In"
                    " Reservation successfull for \"{}\"\n".format(
                        reservation_name), "info")
                status = True
            else:
                testcase_Utils.pNote(
                    "\n\n *** Cloudshell Create Route In"
                    " Reservation failed for \"{}\"".format(reservation_name),
                    "warning")

        except Exception as exception:
            print_exception(exception)

        testcase_Utils.report_substep_status(status)
        return status
    def cs_add_users_to_reservation(self, system_name, reservation_name,
                                    list_of_usernames):
        """Add one or more permitted users to the specified reservation.

        :Datafile usage:
             NA
        :Arguments:
            1. system_name(string) = Name of the UAP system from the datafile
            2. reservation_name(string) = Specify the name of the reservation.
            3. list_of_usernames(list) = list of usernames to permit access to
               reservation.
               For example: To add many users to access the reservation
                            list_of_usernames = ['user1','user2','userx']

        :Returns:
            1. status(bool)= True/False
        """

        wdesc = "Add one or more permitted users to the reservation"
        testcase_Utils.pSubStep(wdesc)
        testcase_Utils.pNote(file_Utils.getDateTime())

        testcase_Utils.pNote("cs_add_users_to_reservation, cs obj-{}".\
                             format(cloud_shell), "info")

        usernames = list_of_usernames[0:]
        testcase_Utils.pNote("cs_add_users_to_reservation, res_name-{},"\
                             "users-{}".format(reservation_name, usernames))

        status = False
        cs_res_id = data_Utils.get_object_from_datarepository\
                    (system_name+"_"+reservation_name+"_reservationId")
        try:
            xml_resp = cloud_shell.AddPermittedUsersToReservation(cs_res_id,\
                                                                  usernames)
            if xml_resp is not None:
                testcase_Utils.pNote("\n\n *** Cloudshell Add users \"{}\" to"
                                     "reservation successfull".\
                                     format(usernames), "info")
                status = True
            else:
                testcase_Utils.pNote(
                    "\n\n *** Cloudshell Add users \"{}\" to"
                    "Reservation failed".format(usernames), "warning")
        except Exception as exception:
            print_exception(exception)

        testcase_Utils.report_substep_status(status)
        return status
    def cs_remove_route_from_reservation(self, system_name, reservation_name,
                                         first_endpoint, second_endpoint,
                                         mapping_type):
        """Disconnects two endpoints and removes the mapped route between
           them

        :Arguments:
            1. system_name(string) = Name of the UAP system from the datafile
            2. reservation_name(string) = Specify the name of the reservation.
            3. first_endpoint(str) = The first endpoint of the two end points
            4. second_endpoint(str) = The second endpoint of the two end points
            5. mapping_type(string) = Specify bi-directional or uni-directional
               as the mapping type
        :Returns:
            1. status(bool) = True/False
        """

        wdesc = "Remove Route From Reservation in CloudShell API Host"
        testcase_Utils.pSubStep(wdesc)
        testcase_Utils.pNote(file_Utils.getDateTime())

        testcase_Utils.pNote(
            "cs_remove_route_from_reservation, cs obj-{}".format(cloud_shell),
            "info")

        status = False
        cs_res_id = data_Utils.get_object_from_datarepository(
            system_name + "_" + reservation_name + "_reservationId")
        list_of_endpoints = [first_endpoint, second_endpoint]
        try:
            xml_resp = cloud_shell.RemoveRoutesFromReservation(
                cs_res_id, list_of_endpoints, mapping_type)
            if xml_resp is not None:
                testcase_Utils.pNote(
                    "\n\n *** Cloudshell Remove Route From"
                    " Reservation successfull for \"{}\"\n".format(
                        reservation_name), "info")
                status = True
            else:
                testcase_Utils.pNote(
                    "\n\n *** Cloudshell Remove Route From"
                    " Reservation failed for \"{}\"".format(reservation_name),
                    "warning")

        except Exception as exception:
            print_exception(exception)

        testcase_Utils.report_substep_status(status)
        return status
    def cs_disconnect_routes(self, system_name, reservation_name,
                             first_endpoint, second_endpoint):
        """Disconnects the routes in the cloud shell

        :Arguments:
            1. system_name(string) = Name of the UAP system from the datafile
            2. reservation_name(string) = Specify the name of the reservation.
            3. first_endpoint(str) = The first endpoint of the two end points
            4. second_endpoint(str) = The second endpoint of the two end points
        :Returns:
            1. status(bool)= True/False
        """

        wdesc = "Disconnect Routes in CloudShell API Host"
        testcase_Utils.pSubStep(wdesc)
        testcase_Utils.pNote(file_Utils.getDateTime())

        testcase_Utils.pNote("cs_disconnect_routes, cs obj-{}".\
                             format(cloud_shell), "info")

        endpoints = [first_endpoint, second_endpoint]

        status = False
        cs_res_id = data_Utils.get_object_from_datarepository\
                (system_name+"_"+reservation_name+"_reservationId")
        try:
            xml_resp = cloud_shell.DisconnectRoutesInReservation(
                cs_res_id, endpoints)
            if xml_resp is not None:
                testcase_Utils.pNote("\n\n *** Cloudshell Disconnect Routes"
                                     " successfull for \"{}\"\n".\
                                     format(reservation_name), "info")
                status = True
            else:
                testcase_Utils.pNote("\n\n *** Cloudshell Disconnect Routes"
                                     " failed for \"{}\"".\
                                     format(reservation_name), "warning")

        except Exception as exception:
            print_exception(exception)

        testcase_Utils.report_substep_status(status)
        return status
    def cs_end_reservation(self, system_name, reservation_name, unmap):
        """End the reservation in Cloudshell

        :Datafile usage:
             NA
        :Arguments:
            1. system_name(string) = Name of the UAP system from the datafile
            2. reservation_name(string) = Specify the name of the reservation.
            3. unmap(string) = true or false, Unmap resources - Specify whether to keep mappings
               or release mapped resources when deleting the reservation.
        :Returns:
            1. status(bool)= True/False
        """

        wdesc = "End Reservation in CloudShell API Host"
        testcase_Utils.pSubStep(wdesc)
        testcase_Utils.pNote(file_Utils.getDateTime())

        testcase_Utils.pNote("cs_end_reservation, cs obj-{}".\
                             format(cloud_shell), "info")

        status = False
        cs_res_id = data_Utils.get_object_from_datarepository\
                   (system_name+"_"+reservation_name+"_reservationId")
        try:
            unmap = unmap.lower()
            xml_resp = cloud_shell.EndReservation(cs_res_id, unmap)
            if xml_resp is not None:
                testcase_Utils.pNote("\n\n *** Cloudshell End reservation"
                                     " successfull for \"{}\"\n".\
                                     format(reservation_name), "info")
                status = True
            else:
                testcase_Utils.pNote("\n\n *** Cloudshell End Reservation"
                                     " failed for \"{}\"".\
                                     format(reservation_name), "warning")

        except Exception as exception:
            print_exception(exception)

        testcase_Utils.report_substep_status(status)
        return status
    def cs_get_reservation_details(self, system_name, reservation_name):
        """Retrieves all details and parameters for a specified reservation

        :Datafile usage:
             NA
        :Arguments:
            1. system_name(string) = Name of the UAP system from the datafile
            2. reservation_name(string) = Specify the name of the reservation.

        :Returns:
            1. status(bool)= True/False
        """

        wdesc = "To retrieve all details and parameters for a specified"\
                "reservation"
        testcase_Utils.pSubStep(wdesc)
        testcase_Utils.pNote(file_Utils.getDateTime())

        status = False
        cs_res_id = data_Utils.get_object_from_datarepository\
                    (system_name+"_"+reservation_name+"_reservationId")
        testcase_Utils.pNote("cs_get_reservation_details, cs obj-{}".\
                             format(cloud_shell), "info")
        try:
            xml_resp = cloud_shell.GetReservationDetails(cs_res_id)
            if xml_resp is not None:
                testcase_Utils.pNote("\n\n *** Get reservation details for "
                                     "\"(%s)\" successfull\n" % (reservation_name),\
                                     "info")
                status = True
            else:
                testcase_Utils.pNote("\n\n *** Get reservation details for "
                                     "\"(%s)\" failed\n" % (reservation_name),\
                                     "warning")
        except Exception as exception:
            print_exception(exception)

        testcase_Utils.report_substep_status(status)
        return status
    def cs_get_current_reservation(self, reservation_owner):
        """Retrieves current reservations for the specified owner

        :Datafile usage:
             NA
        :Arguments:
            1. reservation_owner(string) = Specify the user name of the
               reservation owner.

        :Returns:
            1. status(bool)= True/False
        """

        wdesc = "To retrieve current reservations for the specified owner"
        testcase_Utils.pSubStep(wdesc)
        testcase_Utils.pNote(file_Utils.getDateTime())

        status = False
        testcase_Utils.pNote("cs_get_current_reservation, cs obj-{}".\
                             format(cloud_shell), "info")
        try:
            xml_resp = cloud_shell.GetCurrentReservations(reservation_owner)

            if xml_resp is not None:
                testcase_Utils.pNote("\n\n *** Get current reservation for "
                                     "\"(%s)\" successfull\n" % (reservation_owner),\
                                     "info")
                status = True
            else:
                testcase_Utils.pNote("\n\n *** Get current reservation for "
                                     "\"(%s)\" failed\n" % (reservation_owner),\
                                     "warning")
        except Exception as exception:
            print_exception(exception)

        testcase_Utils.report_substep_status(status)
        return status
    def cs_activate_topology(self,
                             system_name,
                             reservation_name,
                             topology_full_path,
                             time_out=60):
        """Activate Topology to reservation in Cloudshell

        :Datafile usage:
             NA
        :Arguments:
            1. system_name(string) = Name of the UAP system from the datafile
            2. reservation_name(string) = Specify the name of the reservation.
            3. topology_path(string) = Specify the full topology name. Include
               the full path from the root to the topology, separated by slashes.
               For example: FolderName/Topologies/TopologyName
            4. time_out(int): Before activating topology, we need to check status
                of the reservation. If it is started, then we need to activate the
                topology.
                Need to wait for some time before activating topology for
                reservation status to get started, making the default value of
                time_out as 60 sec and can change the value depending on number
                of resources.
        :Returns:
            1. status(bool)= True/False
        """

        wdesc = "Activate Topology to Reservation in CloudShell API Host"
        testcase_Utils.pSubStep(wdesc)
        testcase_Utils.pNote(file_Utils.getDateTime())

        testcase_Utils.pNote("cs_activate_topology, cs obj-{}".\
                             format(cloud_shell), "info")

        status = True
        cs_res_id = data_Utils.get_object_from_datarepository\
                    (system_name+"_"+reservation_name+"_reservationId")

        #Before entering try block to activate the topology,
        #check whether Reservation status is Started. If status is not Started,
        #then wait for time_out seconds before activating.

        # Check for Conflicts
        reservation_status = cloud_shell.GetReservationDetails(
            cs_res_id).ReservationDescription
        if reservation_status.Conflicts:
            conflicts_suggested_end_times = []
            for conflicted_resource in reservation_status.Conflicts:
                planned_end_time = conflicted_resource.ConflictPlannedEndTime
                if planned_end_time not in conflicts_suggested_end_times:
                    conflicts_suggested_end_times.append(planned_end_time)
            # End the Reservation
            cloud_shell.EndReservation(cs_res_id)
            print_error(
                "Conflicts Found, Planned end time for resources inside is:\n{}"
                .format("\n".join(conflicts_suggested_end_times)))
            status = False
            return status

        reservation_status = cloud_shell.GetReservationDetails(
            cs_res_id).ReservationDescription.Status
        sec = 0
        while reservation_status != "Started":
            sec = sec + 1
            reservation_status = cloud_shell.GetReservationDetails(
                cs_res_id).ReservationDescription.Status
            time.sleep(1)
            if sec == int(time_out):
                testcase_Utils.pNote("Waited for {0} seconds, the current reservation"
                                     " status is {1}, but the"
                                     " expected status is Started".\
                                     format(int(time_out), reservation_status),
                                     "warning")
                status = False
                break
        if status:
            try:
                xml_resp = cloud_shell.ActivateTopology(
                    cs_res_id, topology_full_path)
                if xml_resp is not None:
                    testcase_Utils.pNote("\n\n *** Cloudshell Activate Topology-\"{}\""
                                         " successfull for \"{}\"\n".\
                                         format(topology_full_path, reservation_name),\
                                         "info")
                else:
                    testcase_Utils.pNote("\n\n *** Cloudshell Activate Topology-\"{}\""
                                         " failed for \"{}\"".\
                                         format(topology_full_path, reservation_name),
                                         "warning")
                    status = False
            except Exception as exception:
                print_exception(exception)
                status = False
        testcase_Utils.report_substep_status(status)
        return status
    def cs_add_topology_to_reservation(self, system_name, reservation_name,
                                       topology_full_path):
        """
        Create the reservation and add topology to the reservation in Cloudshell

        :Datafile usage:
             NA
        :Arguments:
            1. system_name(string) = Name of the UAP system from the datafile
            2. reservation_name(string) = Specify the name of the reservation.
            3. topology_full_path(string) = Specify the full topology name. Include
               the full path from the root to the topology, separated by slashes.
               For example: FolderName/Topologies/TopologyName

        :Returns:
            1. status(bool)= True/False
        """
        wdesc = "Create the reservation and add Topology to Reservation in CloudShell API Host"
        testcase_Utils.pSubStep(wdesc)
        testcase_Utils.pNote(file_Utils.getDateTime())

        status = True
        res_key = "{0}_{1}_cs_rsrv_details".format(system_name,
                                                   reservation_name)
        res_details = data_Utils.get_object_from_datarepository(res_key)
        output_dict = {}

        if res_details:
            username = res_details["username"]
            reservation_name = res_details["reservation_name"]
            duration = int(res_details["duration"])
            notify_on_start = res_details["notify_on_start"]
            notify_on_end = res_details["notify_on_end"]
            notify_mins_before_end = int(res_details["notify_mins_before_end"])
            try:
                xml_resp = cloud_shell.CreateImmediateTopologyReservation(
                    reservation_name, username, duration, notify_on_start,
                    notify_on_end, notify_mins_before_end, topology_full_path)
                if xml_resp is not None:
                    reservation_id = xml_resp.Reservation.Id
                    output_dict = {
                        'domain_id':
                        cloud_shell.domain,
                        '{0}_{1}_reservationId'.format(system_name, reservation_name):
                        reservation_id
                    }

                    testcase_Utils.pNote("\n\n *** Cloudshell CreateReservation"
                                         " successful for ResName-\"{}\" ResId-{}\n".\
                                         format(reservation_name,
                                                output_dict['{0}_{1}_reservationId'.\
                                                            format(system_name,
                                                                   reservation_name)]),
                                         "info")

                    testcase_Utils.pNote("\n\n *** Cloudshell Add Topology \"{}\""
                                         " successful for \"{}\"\n".\
                                         format(topology_full_path, reservation_name),
                                         "info")

                else:
                    testcase_Utils.pNote(
                        "\n\n *** Cloudshell CreateReservation"
                        " failed for \"{}\"".format(reservation_name),
                        "warning")

                    testcase_Utils.pNote("\n\n *** Cloudshell Add Topology \"{}\""
                                         " failed for \"{}\"".\
                                         format(topology_full_path, reservation_name),
                                         "warning")
                    status = False
            except Exception as exception:
                print_exception(exception)
                status = False
        else:
            pNote("Details for reservation_name={0}, for sysem={1} "\
                  "not found in data repository. Please make sure "\
                  "to execute the keyword '{2}' before this"\
                  "step".format(reservation_name, system_name, 'cs_create_reservation'),
                  "warning")
            status = False

        testcase_Utils.report_substep_status(status)
        return status, output_dict
    def cs_create_topology_reservation(self, system_name, reservation_name,
                                       duration_in_mins, notify_on_start,
                                       notify_on_end, notify_mins_before_end,
                                       topology_full_path):
        """Defines a reservation to be started immediately

        :Datafile usage:
            Tags or attributes to be used in input datafile for the system
            or subsystem.If both tag and attribute is provided the attribute
            will be used.
            1. username   = name of the cloudshell user

        :Arguments:
            1. system_name(string) = Name of the UAP system from the datafile
            2. reservation_name(string) = Specify the name of the reservation.
            3. duration_in_mins(int) = Specify the length of the reservation.
            4. notify_on_start(string) = true or false, Indicate whether to notify the
               reservation owner when the reservation starts.
            5. notify_on_end(string) = true or false, Indicate whether to notify the reservation
               owner when the reservation ends.
            6. notify_mins_before_end(int) = Notification Minutes Before End -
               Indicate the number of minutes before the end of the reservation
               to send out a Notify On End alert to the reservation owner.
               (0 = disabled)
            7. topology_full_path(string) = Specify the full topology name. Include
               the full path from the root to the topology, separated by slashes.
               For example: FolderName/Topologies/TopologyName

        :Returns:
            1. status(bool)= True/False
            2. output_dict = consists of following key value pairs:
               1. domain_id: Domain Id returned after login to cloudshell.
               2. reservation_id: Reservation Id returned after successful
                  creation of resources.
        """

        wdesc = "Create Topology Reservation in CloudShell API Host"
        testcase_Utils.pSubStep(wdesc)
        testcase_Utils.pNote(file_Utils.getDateTime())

        testcase_Utils.pNote("cs_create_topology_reservation, cs obj-{}".\
                             format(cloud_shell), "info")

        keys_for_credentials = ['username']
        credentials = data_Utils.get_credentials(self.datafile, system_name,
                                                 keys_for_credentials)

        status = False
        output_dict = {}
        notify_on_start = notify_on_start.lower()
        notify_on_end = notify_on_end.lower()
        try:
            xml_resp = cloud_shell.CreateImmediateTopologyReservation(
                reservation_name, credentials['username'],
                int(duration_in_mins), notify_on_start, notify_on_end,
                int(notify_mins_before_end), topology_full_path)
            if xml_resp is not None:
                reservation_id = xml_resp.Reservation.Id
                output_dict = {
                    'domain_id':
                    cloud_shell.domain,
                    '{0}_{1}_reservationId'.format(system_name, reservation_name):
                    reservation_id
                }
                testcase_Utils.pNote("\n\n *** Cloudshell CreateTopologyReservation"
                                     " successfull for ResName-\"{}\" ResId-{}\n".\
                                     format(reservation_name,
                                            output_dict['{0}_{1}_reservationId'.\
                                                        format(system_name, reservation_name)]),
                                     "info")
                status = True
            else:
                testcase_Utils.pNote(
                    "\n\n *** Cloudshell CreateTopologyReservation"
                    " failed for \"{}\"".format(reservation_name), "warning")
        except Exception as exception:
            print_exception(exception)

        testcase_Utils.report_substep_status(status)
        return status, output_dict
    def cs_create_reservation(self, system_name, reservation_name,
                              duration_in_mins, notify_on_start, notify_on_end,
                              notify_mins_before_end):
        """
        Defines a reservation to be created.

        This keyword only defines the reservation with all its details by saving
        the details in the data repository. Actual creation is done by using the
        cs_add_topology_to_reservation keyword by providing the reservation name
        to it.

        :Datafile usage:
            Tags or attributes to be used in input datafile for the system
            or subsystem.If both tag and attribute is provided the attribute
            will be used.
            1. username   = name of the cloudshell user

        :Arguments:
            1. system_name(string) = Name of the UAP system from the datafile
            2. reservation_name(string) = Specify the name of the reservation.
            3. duration_in_mins(int) = Specify the length of the reservation.
            4. notify_on_start(string) = true or false, Indicate whether to notify the
               reservation owner when the reservation starts.
            5. notify_on_end(string) = true or false, Indicate whether to notify the reservation
               owner when the reservation ends.
            6. notify_mins_before_end(int) = Notification Minutes Before End -
               Indicate the number of minutes before the end of the reservation
               to send out a Notify On End alert to the reservation owner.
               (0 = disabled)

        :Returns:
            1. status(bool)= True/False
            2. output_dict = consists of following key value pairs:
               1. domain_id: Domain Id returned after login to cloudshell.
               2. reservation_id: Reservation Id returned after successful
                  creation of resources.
        """

        wdesc = "Save reservation details for the reservation name provided"
        testcase_Utils.pSubStep(wdesc)
        testcase_Utils.pNote(file_Utils.getDateTime())

        testcase_Utils.pNote("save reservation, cs obj-{}".\
                             format(cloud_shell), "info")

        keys_for_credentials = ['username']
        credentials = data_Utils.get_credentials(self.datafile, system_name,
                                                 keys_for_credentials)

        status = True
        output_dict = {}
        try:
            pNote("This keyword will only collect the reservation information "\
                  "and save the details in data repository.\n")
            pNote("In order to create reservation in cloudshell, execute this keyword and then "\
                  "use the keyword 'cs_add_topology_to_reservation' and provide the "\
                  "reservation_name to it, 'cs_add_topology_to_reservation' keyword will use "\
                  "the reservation  details for he reservation_name provided, create a "\
                  "reservation and add topology to the reservation.")

            res_key = "{0}_{1}_cs_rsrv_details".format(system_name,
                                                       reservation_name)
            notify_on_start = notify_on_start.lower()
            notify_on_end = notify_on_end.lower()
            output_dict = {
                res_key: {
                    "reservation_name": reservation_name,
                    "username": credentials['username'],
                    "duration": duration_in_mins,
                    "notify_on_start": notify_on_start,
                    "notify_on_end": notify_on_end,
                    "notify_mins_before_end": notify_mins_before_end
                }
            }

        except Exception as exception:
            pNote("Saving reservation details for reservation_name={0} failed!!"\
                  .format(reservation_name))
            print_exception(exception)
            status = False
        else:
            pNote("Sucessfully saved reservation details for reservation_name={0}"\
                  .format(reservation_name))

        testcase_Utils.report_substep_status(status)
        return status, output_dict
    def cs_reservation(self, system_name, reservation_name, duration_in_mins,
                       topology_full_path):
        """
        Defines a reservation to be created.

        This keyword only defines the reservation with all its details by saving
        the details in the data repository. Actual creation is done by using the
        cs_reservation keyword by providing the reservation name
        to it.

        :Datafile usage:
            Tags or attributes to be used in input datafile for the system
            or subsystem.If both tag and attribute is provided the attribute
            will be used.
            1. username   = name of the cloudshell user

        :Arguments:
            1. system_name(string) = Name of the UAP system from the datafile
            2. reservation_name(string) = Specify the name of the reservation.
            3. duration_in_mins(int) = Specify the length of the reservation.
            4. topology_full_path(str) = Specify the full path of the reservation.

        :Returns:
            1. status(bool)= True/False
        """
        try:
            from cloudshell.api.cloudshell_api import CloudShellAPISession
            from cloudshell.api.common_cloudshell_api import CloudShellAPIError
        except ImportError:
            print_info("{0}: Cloudshell Python Package is not installed".\
                       format(os.path.abspath(__file__)))
            print_info("Please install latest Cloudshell Python Package.")

        api = self._create_cs_obj(system_name)
        flag = True
        output_dict = {}
        wdesc = "Save reservation details for the reservation name provided"
        testcase_Utils.pSubStep(wdesc)
        testcase_Utils.pNote(file_Utils.getDateTime())
        testcase_Utils.pNote("save reservation, cs obj-{}".\
                             format(api), "info")
        testcase_Utils.pNote("Login, cs obj-{}".format(api), "info")

        if api is not None:
            testcase_Utils.pNote("\n\n *** Login to Cloudshell System-{}"
                                 " successfull, domain-{}\n".\
                                 format(api.host,\
                                 api.domain), "info")

        keys_for_credentials = ['username']
        credentials = data_Utils.get_credentials(self.datafile, system_name,
                                                 keys_for_credentials)

        pNote("This keyword will only collect the reservation information "\
              "and save the details in data repository.\n")
        res_key = "{0}_{1}_cs_rsrv_details".format(system_name,
                                                   reservation_name)
        output_dict = {
            res_key: {
                "reservation_name": reservation_name,
                "username": credentials['username'],
                "duration": duration_in_mins,
                "topology_full_path": topology_full_path
            },
        }
        pNote("The CloudShell Reservation Provided Details is :{}".format(
            output_dict))

        blueprint_to_reserve = topology_full_path
        reservation_time = duration_in_mins
        blueprint_owner = credentials['username']
        reservation_name = reservation_name
        # Do reservation
        try:
            result = api.CreateImmediateTopologyReservation(reservationName=reservation_name, \
                                                            owner=blueprint_owner,
                                                            durationInMinutes=reservation_time,
                                                            topologyFullPath=\
                                                                blueprint_to_reserve).Reservation

            reservation_id = result.Id
            reservation_details = api.GetReservationDetails(
                reservation_id).ReservationDescription
            # Check for Conflicts
            if reservation_details.Conflicts:
                conflicts_suggested_end_times = []
                for conflicted_resource in reservation_details.Conflicts:
                    planned_end_time = conflicted_resource.ConflictPlannedEndTime
                    if planned_end_time is None:
                        continue
                    if planned_end_time not in conflicts_suggested_end_times:
                        conflicts_suggested_end_times.append(planned_end_time)
                # End the Reservation
                api.EndReservation(reservation_id)
                msg = "Conflicts Found, Planned end time for resources inside \
                is:\n{}".format("\n".join(conflicts_suggested_end_times))
                raise CloudShellAPIError(102, msg, "")

            # Wait for Sandbox to be ready
            wait_timeout = 100  # seconds
            now = datetime.datetime.now()
            while wait_timeout > (datetime.datetime.now() - now).seconds:
                status = api.GetReservationStatus(
                    reservation_id).ReservationSlimStatus
                if status.ProvisioningStatus == "Error":
                    api.EndReservation(reservation_id)
                    raise CloudShellAPIError(102, "Error with Setup workflow",
                                             "")
                elif status.ProvisioningStatus == "Ready" or status.ProvisioningStatus == "Not Run":
                    pNote(
                        " CloudShell Reservation made successfully. ID is: {}".
                        format(reservation_id))
                    flag = True
                    break
                time.sleep(1)
            else:
                api.EndReservation(reservation_id)
                raise CloudShellAPIError(
                    102, "No positive status return for reservation \
                after {} seconds".format(wait_timeout), "")

        except CloudShellAPIError as cs_err:
            # Example error check for user
            if 'User "{}" does not exist'.format(
                    blueprint_owner) == cs_err.message:
                raise Exception("No user name: {}".format(blueprint_owner))
            # Example error check for blueprint
            elif 'Topology \'{}\' was not found'.format(
                    blueprint_to_reserve) == cs_err.message:
                raise Exception(
                    "No blueprint with name: {}".format(blueprint_to_reserve))
            # Generic raise error from cloudshell
            raise Exception(cs_err.message)
        except Exception as e:
            # other non-cloudshell errors
            raise
        else:
            pNote("Sucessfully saved reservation details for reservation_name={0}"\
                  .format(reservation_name))
        return flag