def fabric_principal(login, password, fos_ip_addr, ssh_hostkeymust):
    enabled_err = None
    enabled = False
    priority_err = None
    priority = ""

    rssh, sshstr = ssh_and_configure(login, password, fos_ip_addr,
                                     ssh_hostkeymust, "fabricprincipal",
                                     "showcommand")
    if rssh == 0:
        if "Principal Selection Mode: Enable" in sshstr:
            enabled = True
        elif "Principal Selection Mode: Disable" in sshstr:
            enabled = False
        else:
            enabled_err = "fabric-principal-enabed returned unknown string"

        if "Principal Switch Selection Priority: " in sshstr:
            line = sshstr[sshstr.find("Principal Switch Selection Priority: "
                                      ):]
            priority_str = line[len("Principal Switch Selection Priority: "):]
            priority = priority_str.rstrip()
        else:
            priority_err = "fabric-principal-priority returned unknown string"

    return enabled_err, enabled, priority_err, priority
def fabric_get(login, password, fos_ip_addr, fos_version, is_https, auth, vfid,
               result, ssh_hostkeymust):
    """
        retrieve existing switch configurations

        :param fos_ip_addr: ip address of FOS switch
        :type fos_ip_addr: str
        :param is_https: indicate to use HTTP or HTTPS
        :type is_https: bool
        :param auth: authorization struct from login
        :type auth: dict
        :param result: dict to keep track of execution msgs
        :type result: dict
        :return: code to indicate failure or success
        :rtype: int
        :return: dict of fabric configurations
        :rtype: dict
    """
    full_fabric_url, validate_certs = full_url_get(is_https, fos_ip_addr,
                                                   REST_FABRIC)

    rtype, rdict = url_get_to_dict(fos_ip_addr, is_https, auth, vfid, result,
                                   full_fabric_url)
    if rtype != 0:
        result["failed"] = True
        result["msg"] = "API failed to return data"
        return -1, None

    rssh, sshstr = ssh_and_configure(login, password, fos_ip_addr,
                                     ssh_hostkeymust, "iodshow", "showcommand")
    if rssh == 0:
        if "IOD is not set" in sshstr:
            rdict["Response"]["fabric"]["in-order-delivery-enabled"] = "false"
        elif "IOD is set" in sshstr:
            rdict["Response"]["fabric"]["in-order-delivery-enabled"] = "true"
        else:
            result["failed"] = True
            result["msg"] = "IOD returned unknown string. " + sshstr
            return -1, None

    enabled_err, enabled, priority_err, priority = fabric_principal(
        login, password, fos_ip_addr, ssh_hostkeymust)
    if enabled_err == None:
        if enabled:
            rdict["Response"]["fabric"]["fabric-principal-enabled"] = "true"
        else:
            rdict["Response"]["fabric"]["fabric-principal-enabled"] = "false"
    else:
        result["failed"] = True
        result["msg"] = enabled_err
        return -1, None

    if priority_err == None:
        rdict["Response"]["fabric"]["fabric-principal-priority"] = priority
    else:
        result["failed"] = True
        result["msg"] = priority_err
        return -1, None

    return 0, rdict
def fc_switch_get(login, password, fos_ip_addr, fos_version, is_https, auth,
                  vfid, result, ssh_hostkeymust, timeout):
    """
        retrieve existing switch configurations

        :param fos_ip_addr: ip address of FOS switch
        :type fos_ip_addr: str
        :param is_https: indicate to use HTTP or HTTPS
        :type is_https: bool
        :param auth: authorization struct from login
        :type auth: dict
        :param result: dict to keep track of execution msgs
        :type result: dict
        :return: code to indicate failure or success
        :rtype: int
        :return: dict of switch configurations
        :rtype: dict
    """
    full_fc_switch_url, validate_certs = full_url_get(is_https, fos_ip_addr,
                                                      REST_SWITCH)

    rtype, rdict = url_get_to_dict(fos_ip_addr, is_https, auth, vfid, result,
                                   full_fc_switch_url, timeout)

    if rtype != 0:
        result["failed"] = True
        result["msg"] = "API failed to return data"
        return -1, None

    result["fos_version"] = fos_version
    result["fos_version_check"] = fos_version < "v9.0"
    if fos_version < "v9.0":
        rssh, sshstr = ssh_and_configure(login, password, fos_ip_addr,
                                         ssh_hostkeymust, "dlsshow",
                                         "showcommand")
        if rssh == 0:
            if "DLS is not set with Lossless disabled" in sshstr or "Error: This command is not supported in AG mode" in sshstr:
                rdict["Response"]["fibrechannel-switch"][
                    "dynamic-load-sharing"] = "disabled"
            elif "DLS is set with Lossless disabled" in sshstr:
                rdict["Response"]["fibrechannel-switch"][
                    "dynamic-load-sharing"] = "dls"
            elif "DLS is set with Lossless enabled, Two-hop Lossless disabled" in sshstr:
                rdict["Response"]["fibrechannel-switch"][
                    "dynamic-load-sharing"] = "lossless-dls"
            elif "DLS is set with Two-hop Lossless enabled" in sshstr:
                rdict["Response"]["fibrechannel-switch"][
                    "dynamic-load-sharing"] = "two-hop-lossless-dls"
            else:
                result["failed"] = True
                result["msg"] = "DLS returned unknown string"
                return -1, None

    return 0, rdict
def port_configuration_get(login, password, fos_ip_addr, fos_version, is_https,
                           auth, vfid, result, ssh_hostkeymust, timeout):
    """
        retrieve existing port configurations

        :param fos_ip_addr: ip address of FOS switch
        :type fos_ip_addr: str
        :param is_https: indicate to use HTTP or HTTPS
        :type is_https: bool
        :param auth: authorization struct from login
        :type auth: dict
        :param result: dict to keep track of execution msgs
        :type result: dict
        :return: code to indicate failure or success
        :rtype: int
        :return: dict of fabric configurations
        :rtype: dict
    """
    full_port_config_url, validate_certs = full_url_get(
        is_https, fos_ip_addr, REST_PORT_CONFIGURATION)

    rtype, rdict = url_get_to_dict(fos_ip_addr, is_https, auth, vfid, result,
                                   full_port_config_url, timeout)
    if rtype != 0:
        result["failed"] = True
        result["msg"] = "API failed to return data"
        return -1, None

    rssh, sshstr = ssh_and_configure(login, password, fos_ip_addr,
                                     ssh_hostkeymust, "creditrecovmode --show",
                                     "showcommand")
    if rssh == 0:
        if "Internal port credit recovery is Disabled" in sshstr:
            rdict["Response"]["port-configuration"][
                "credit-recovery-mode"] = "off"
        elif "Internal port credit recovery is Enabled with LrOnly" in sshstr:
            rdict["Response"]["port-configuration"][
                "credit-recovery-mode"] = "onLrOnly"
        elif "Internal port credit recovery is Enabled with LrThresh" in sshstr:
            rdict["Response"]["port-configuration"][
                "credit-recovery-mode"] = "onLrThresh"
        elif "Not supported on this platform" in sshstr:
            result["credit_recovery_mode"] = "Not supported on this platform"
        else:
            result["failed"] = True
            result["msg"] = "credit-recovery-mode returned unknown string"
            return -1, None

    return 0, rdict
Esempio n. 5
0
def v3_trap_patch(login, password, fos_ip_addr, fos_version, is_https, auth,
                  vfid, result, v3_traps, ssh_hostkeymust, timeout):
    """
        update existing user config configurations

        :param fos_ip_addr: ip address of FOS switch
        :type fos_ip_addr: str
        :param is_https: indicate to use HTTP or HTTPS
        :type is_https: bool
        :param auth: authorization struct from login
        :type struct: dict
        :param result: dict to keep track of execution msgs
        :type result: dict
        :param diff_attributes: list of attributes for update
        :type ports: dict
        :return: code to indicate failure or success
        :rtype: int
        :return: list of dict of chassis configurations
        :rtype: list
    """
    l_v3_traps = v3_traps[:]

    if fos_version < "v9.0":
        for l_v3_trap in l_v3_traps:
            if "host" in l_v3_trap and l_v3_trap["host"] == "0.0.0.0":
                rssh, sshstr = ssh_and_configure(
                    login, password, fos_ip_addr, ssh_hostkeymust,
                    "snmpconfig --set snmpv3 -index " +
                    str(l_v3_trap["trap-index"]) + " -host 0.0.0.0",
                    "Committing configuration.....done.")
                if rssh != 0:
                    result["failed"] = True
                    result[
                        "msg"] = "Failed to reset host IP to 0.0.0.0. " + sshstr
                else:
                    result["changed"] = True
                    result["messages"] = "IP is reset to 0.0.0.0"

                l_v3_trap.pop("host")

    rest_v3_traps = []

    for l_v3_trap in l_v3_traps:
        if len(l_v3_trap) > 1:
            rest_v3_traps.append(l_v3_trap)

    return rest_v3_traps
Esempio n. 6
0
def chassis_get(login, password, fos_ip_addr, fos_version, is_https, auth,
                vfid, result, ssh_hostkeymust, timeout):
    """
        retrieve existing switch configurations

        :param fos_ip_addr: ip address of FOS switch
        :type fos_ip_addr: str
        :param is_https: indicate to use HTTP or HTTPS
        :type is_https: bool
        :param auth: authorization struct from login
        :type auth: dict
        :param result: dict to keep track of execution msgs
        :type result: dict
        :return: code to indicate failure or success
        :rtype: int
        :return: dict of chassis configurations
        :rtype: dict
    """
    full_chassis_url, validate_certs = full_url_get(is_https, fos_ip_addr,
                                                    REST_CHASSIS)

    rtype, rdict = url_get_to_dict(fos_ip_addr, is_https, auth, vfid, result,
                                   full_chassis_url, timeout)
    if rtype != 0:
        result["failed"] = True
        result["msg"] = "API failed to return data"
        return -1, None

    rssh, sshstr = ssh_and_configure(login, password, fos_ip_addr,
                                     ssh_hostkeymust, "timeout", "showcommand")
    if rssh == 0:
        if "Current IDLE Timeout is " in sshstr:
            text = sshstr[len("Current IDLE Timeout is "):]
            timeout = text.split(" ")
            rdict["Response"]["chassis"]["telnet-timeout"] = timeout[0]
        elif "Shell Idle Timeout is " in sshstr:
            text = sshstr[len("Shell Idle Timeout is "):]
            timeout = text.split(" ")
            rdict["Response"]["chassis"]["telnet-timeout"] = timeout[0]
        else:
            result["failed"] = True
            result["msg"] = "telnet_timeout returned unknown string"
            return -1, None

    return 0, rdict
Esempio n. 7
0
def chassis_patch(login, password, fos_ip_addr, fos_version, is_https, auth,
                  vfid, result, diff_attributes, ssh_hostkeymust, timeout):
    """
        update existing switch configurations

        :param fos_ip_addr: ip address of FOS switch
        :type fos_ip_addr: str
        :param is_https: indicate to use HTTP or HTTPS
        :type is_https: bool
        :param auth: authorization struct from login
        :type auth: dict
        :param result: dict to keep track of execution msgs
        :type result: dict
        :param diff_attributes: list of attributes for update
        :type ports: dict
        :return: code to indicate failure or success
        :rtype: int
        :return: list of dict of chassis configurations
        :rtype: list
    """
    l_diffs = diff_attributes.copy()

    if "telnet-timeout" in l_diffs:
        rssh, sshstr = ssh_and_configure(
            login, password, fos_ip_addr, ssh_hostkeymust,
            "timeout " + str(l_diffs["telnet-timeout"]),
            "Timeout will be in effect after NEXT login")
        if rssh != 0:
            result["failed"] = True
            result["msg"] = "Failed to set telnet-timeout. " + sshstr
        else:
            result["changed"] = True
            result["messages"] = "telnet-timeout set"
        l_diffs.pop("telnet-timeout")

    if len(l_diffs) == 0:
        return 0

    full_chassis_url, validate_certs = full_url_get(is_https, fos_ip_addr,
                                                    REST_CHASSIS)

    return (url_patch_single_object(fos_ip_addr, is_https, auth, vfid, result,
                                    full_chassis_url, "chassis", l_diffs,
                                    timeout))
def fc_switch_patch(login, password, fos_ip_addr, fos_version, is_https, auth,
                    vfid, result, diff_attributes):
    """
        update existing switch configurations

        :param fos_ip_addr: ip address of FOS switch
        :type fos_ip_addr: str
        :param is_https: indicate to use HTTP or HTTPS
        :type is_https: bool
        :param auth: authorization struct from login
        :type auth: dict
        :param result: dict to keep track of execution msgs
        :type result: dict
        :param diff_attributes: list of attributes for update
        :type ports: dict
        :return: code to indicate failure or success
        :rtype: int
        :return: dict of switch configurations
        :rtype: dict
    """
    l_diffs = diff_attributes.copy()

    if fos_version < "v9.0":
        if "dynamic-load-sharing" in l_diffs:
            if l_diffs["dynamic-load-sharing"] == "disabled":
                rssh, sshstr = ssh_and_configure(login, password, fos_ip_addr,
                                                 False,
                                                 "dlsset --disable -lossless",
                                                 "Lossless is not set")
                if rssh != 0:
                    result["failed"] = True
                    result["msg"] = "Failed to disable DLS lossless"
                else:
                    rssh, sshstr = ssh_and_configure(
                        login, password, fos_ip_addr, False,
                        "dlsset --disable -twohop",
                        "Two-hop lossless is not set")
                    if rssh != 0:
                        result["failed"] = True
                        result["msg"] = "Failed to disable DLS twohop"
                    else:
                        result["changed"] = True
            elif l_diffs["dynamic-load-sharing"] == "lossless-dls":
                rssh, sshstr = ssh_and_configure(login, password, fos_ip_addr,
                                                 False,
                                                 "dlsset --enable -lossless",
                                                 "Lossless is set")
                if rssh != 0:
                    result["failed"] = True
                    result["msg"] = "Failed to enable DLS lossless"
                else:
                    rssh, sshstr = ssh_and_configure(
                        login, password, fos_ip_addr, False,
                        "dlsset --disable -twohop", [
                            "Two-hop lossless disabled successfully",
                            "Two-hop lossless is not set"
                        ])
                    if rssh != 0:
                        result["failed"] = True
                        result["msg"] = "Failed to disable DLS twohop"
                    else:
                        result["changed"] = True
                        result["messages"] = "disabled DSL twohop"
            elif l_diffs["dynamic-load-sharing"] == "two-hop-lossless-dls":
                rssh, sshstr = ssh_and_configure(login, password, fos_ip_addr,
                                                 False,
                                                 "dlsset --enable -lossless",
                                                 "Lossless is set")
                if rssh != 0:
                    result["failed"] = True
                    result["msg"] = "Failed to enable DLS lossless"
                else:
                    rssh, sshstr = ssh_and_configure(
                        login, password, fos_ip_addr, False,
                        "dlsset --enable -twohop",
                        "Two-hop lossless enabled successfully")
                    if rssh != 0:
                        result["failed"] = True
                        result["msg"] = "Failed to enable DLS twohop"
                    else:
                        result["changed"] = True
                        result["messages"] = "enable DSL two-hop-lossless-dls"
            else:
                result["failed"] = True
                result["msg"] = "Unkown DLS mode"
            l_diffs.pop("dynamic-load-sharing")

    # should be only key for the switch if nothing else
    if len(l_diffs) <= 1:
        return 0

    full_fc_switch_url = (HTTPS if is_https else HTTP) +\
        fos_ip_addr + REST_SWITCH

    return (url_patch_single_object(fos_ip_addr, is_https, auth, vfid, result,
                                    full_fc_switch_url, "fibrechannel-switch",
                                    l_diffs))
def port_configuration_patch(login, password, fos_ip_addr, fos_version,
                             is_https, auth, vfid, result, diff_attributes,
                             ssh_hostkeymust):
    """
        :param fos_ip_addr: ip address of FOS switch
        :type fos_ip_addr: str
        :param is_https: indicate to use HTTP or HTTPS
        :type is_https: bool
        :param auth: authorization struct from login
        :type auth: dict
        :param result: dict to keep track of execution msgs
        :type result: dict
        :param diff_attributes: list of attributes for update
        :type ports: dict
        :return: code to indicate failure or success
        :rtype: int
        :return: dict of port-configuration configurations
        :rtype: dict
    """
    l_diffs = diff_attributes.copy()

    if "credit-recovery-mode" in l_diffs:
        if l_diffs["credit-recovery-mode"] == "off":
            rssh, sshstr = ssh_and_configure(login, password, fos_ip_addr,
                                             ssh_hostkeymust,
                                             "creditrecovmode --cfg off", "")
            if rssh != 0:
                result["failed"] = True
                result[
                    "msg"] = "Failed to set credit-recovery-mode to off. " + sshstr
            else:
                result["changed"] = True
                result["messages"] = "credit-recovery-mode set to off"
        elif l_diffs["credit-recovery-mode"] == "onLrOnly":
            rssh, sshstr = ssh_and_configure(login, password, fos_ip_addr,
                                             ssh_hostkeymust,
                                             "creditrecovmode --cfg onLrOnly",
                                             "")
            if rssh != 0:
                result["failed"] = True
                result[
                    "msg"] = "Failed to credit-recovery-mode to onLrOnly. " + sshstr
            else:
                result["changed"] = True
                result["messages"] = "credit-recovery-mode set to onLrOnly"
        elif l_diffs["credit-recovery-mode"] == "onLrThresh":
            rssh, sshstr = ssh_and_configure(
                login, password, fos_ip_addr, ssh_hostkeymust,
                "creditrecovmode --cfg onLrThresh", "")
            if rssh != 0:
                result["failed"] = True
                result[
                    "msg"] = "Failed to credit-recovery-mode to onLrThresh. " + sshstr
            else:
                result["changed"] = True
                result["messages"] = "credit-recovery-mode set to onLrThresh"
        else:
            result["failed"] = True
            result["msg"] = "unknown credit-recovery-mode value"
        l_diffs.pop("credit-recovery-mode")

    if len(l_diffs) == 0:
        return 0

    full_port_config_url, validate_certs = full_url_get(
        is_https, fos_ip_addr, REST_PORT_CONFIGURATION)

    return (url_patch_single_object(fos_ip_addr, is_https, auth, vfid, result,
                                    full_port_config_url, "port-configuration",
                                    l_diffs))
def fabric_patch(login, password, fos_ip_addr, fos_version, is_https, auth,
                 vfid, result, diff_attributes, ssh_hostkeymust):
    """
        :param fos_ip_addr: ip address of FOS switch
        :type fos_ip_addr: str
        :param is_https: indicate to use HTTP or HTTPS
        :type is_https: bool
        :param auth: authorization struct from login
        :type auth: dict
        :param result: dict to keep track of execution msgs
        :type result: dict
        :param diff_attributes: list of attributes for update
        :type ports: dict
        :return: code to indicate failure or success
        :rtype: int
        :return: dict of fabric configurations
        :rtype: dict
    """
    l_diffs = diff_attributes.copy()

    if "in-order-delivery-enabled" in l_diffs:
        if l_diffs["in-order-delivery-enabled"] == "true":
            rssh, sshstr = ssh_and_configure(login, password, fos_ip_addr,
                                             ssh_hostkeymust, "iodset",
                                             "IOD is set")
            if rssh != 0:
                result["failed"] = True
                result["msg"] = "Failed to set IOD. " + sshstr
            else:
                result["changed"] = True
                result["messages"] = "in-order-delivery-enabled set"
        elif l_diffs["in-order-delivery-enabled"] == "false":
            rssh, sshstr = ssh_and_configure(login, password, fos_ip_addr,
                                             ssh_hostkeymust, "iodreset",
                                             "IOD is not set")
            if rssh != 0:
                result["failed"] = True
                result["msg"] = "Failed to reset IOD. " + sshstr
            else:
                result["changed"] = True
                result["messages"] = "in-order-delivery-enabled reset"
        else:
            result["failed"] = True
            result["msg"] = "Failed to reset IOD. Invalid input."
        l_diffs.pop("in-order-delivery-enabled")

    if "fabric-principal-priority" in l_diffs and "fabric-principal-enabled" in l_diffs:
        # if both are given, execute the CLI
        if l_diffs["fabric-principal-enabled"] == "true":
            rssh, sshstr = ssh_and_configure(
                login, password, fos_ip_addr, ssh_hostkeymust,
                "fabricprincipal --enable -p " +
                l_diffs["fabric-principal-priority"] + " -f",
                "Principal Selection Mode enabled")
            if rssh != 0:
                result["failed"] = True
                result["msg"] = "Failed to set fabric-principal. " + sshstr
            else:
                result["changed"] = True
                result["messages"] = "fabric-principal-enabled set"
        elif l_diffs["fabric-principal-enabled"] == "false":
            #if disabling, must set the priority to 0
            if l_diffs["fabric-principal-priority"] != "0":
                result["failed"] = True
                result["msg"] = "Priority must be 0 when disabling"
            else:
                rssh, sshstr = ssh_and_configure(
                    login, password, fos_ip_addr, ssh_hostkeymust,
                    "fabricprincipal --disable",
                    "Principal Selection Mode disabled")
                if rssh != 0:
                    result["failed"] = True
                    result["msg"] = "Failed to set fabric-principal. " + sshstr
                else:
                    result["changed"] = True
                    result["messages"] = "fabric-principal-enabled reset"
        else:
            result["failed"] = True
            result["msg"] = "Failed to set fabric-principal. Invalid input."
        l_diffs.pop("fabric-principal-enabled")
        l_diffs.pop("fabric-principal-priority")
    else:
        if "fabric-principal-priority" in l_diffs:
            enabled_err, enabled, priority_err, priority = fabric_principal(
                login, password, fos_ip_addr, ssh_hostkeymust)
            if enabled_err is None and enabled:
                rssh, sshstr = ssh_and_configure(
                    login, password, fos_ip_addr, ssh_hostkeymust,
                    "fabricprincipal --enable -p " +
                    l_diffs["fabric-principal-priority"] + " -f",
                    "Principal Selection Mode enabled")
                if rssh != 0:
                    result["failed"] = True
                    result[
                        "msg"] = "Failed to set fabric-principal-priority. " + sshstr
                else:
                    result["changed"] = True
                    result["messages"] = "fabric-principal-priority set"
            else:
                result["failed"] = True
                result[
                    "msg"] = "fabric-principal-priority must be accompanied by fabric-principal-enabled"
            l_diffs.pop("fabric-principal-priority")

        if "fabric-principal-enable" in l_diffs:
            result["failed"] = True
            result[
                "msg"] = "fabric-principal-enabled must be accompanied by fabric-principal-priority"
            l_diffs.pop("fabric-principal-enabled")

    if len(l_diffs) == 0:
        return 0

    full_fabric_url, validate_certs = full_url_get(is_https, fos_ip_addr,
                                                   REST_FABRIC)

    return (url_patch_single_object(fos_ip_addr, is_https, auth, vfid, result,
                                    full_fabric_url, "fabric", l_diffs))
Esempio n. 11
0
def user_config_patch(login, password, fos_ip_addr, fos_version, is_https,
                      auth, vfid, result, users):
    """
        update existing user config configurations

        :param fos_ip_addr: ip address of FOS switch
        :type fos_ip_addr: str
        :param is_https: indicate to use HTTP or HTTPS
        :type is_https: bool
        :param auth: authorization struct from login
        :type struct: dict
        :param result: dict to keep track of execution msgs
        :type result: dict
        :param diff_attributes: list of attributes for update
        :type ports: dict
        :return: code to indicate failure or success
        :rtype: int
        :return: list of dict of chassis configurations
        :rtype: list
    """
    l_users = users[:]

    if fos_version < "v9.0":
        # walk through all the users and check for account-enabled
        # if pre 9.0 since the attribute patch is not supported pre
        for l_user in l_users:
            if "account-enabled" in l_user:
                if l_user["account-enabled"] == "true":
                    rssh, sshstr = ssh_and_configure(
                        login, password, fos_ip_addr, False,
                        "userconfig --change " + l_user["name"] + " -e yes",
                        "")
                    if rssh != 0:
                        result["failed"] = True
                        result["msg"] = "Failed to enable account"
                    else:
                        result["changed"] = True
                        result["messages"] = "account enabled"
                elif l_user["account-enabled"] == "false":
                    rssh, sshstr = ssh_and_configure(
                        login, password, fos_ip_addr, False,
                        "userconfig --change " + l_user["name"] + " -e no", "")
                    if rssh != 0:
                        result["failed"] = True
                        result["msg"] = "Failed to disable account"
                    else:
                        result["changed"] = True
                        result["messages"] = "account disabled"
                else:
                    result["failed"] = True
                    result[
                        "msg"] = "unknown account-enabled value. Invalid input"
                l_user.pop("account-enabled")

        rest_users = []
        for l_user in l_users:
            if len(l_user) > 1:
                rest_users.append(l_user)

    if len(rest_users) == 0:
        return 0

    full_url = (HTTPS if is_https else HTTP) +\
        fos_ip_addr + REST_USER_CONFIG

    xml_str = user_config_xml_str(result, rest_users)

    result["patch_user_config_str"] = xml_str

    return url_patch(fos_ip_addr, is_https, auth, vfid, result, full_url,
                     xml_str)
def fc_switch_patch(login, password, fos_ip_addr, fos_version, is_https, auth,
                    vfid, result, diff_attributes, ssh_hostkeymust, timeout):
    """
        update existing switch configurations

        :param fos_ip_addr: ip address of FOS switch
        :type fos_ip_addr: str
        :param is_https: indicate to use HTTP or HTTPS
        :type is_https: bool
        :param auth: authorization struct from login
        :type auth: dict
        :param result: dict to keep track of execution msgs
        :type result: dict
        :param diff_attributes: list of attributes for update
        :type ports: dict
        :return: code to indicate failure or success
        :rtype: int
        :return: dict of switch configurations
        :rtype: dict
    """
    l_diffs = diff_attributes.copy()

    if fos_version < "v9.0":
        in_mode_3 = False

        rssh, sshstr = ssh_and_configure(login, password, fos_ip_addr,
                                         ssh_hostkeymust, "aptpolicy",
                                         "showcommand")
        if rssh == 0:
            if "Current Policy: 3" in sshstr:
                in_mode_3 = True

        result["aptpolicy 3"] = in_mode_3

        if "dynamic-load-sharing" in l_diffs:
            if l_diffs["dynamic-load-sharing"] == "disabled":
                if in_mode_3:
                    result["failed"] = True
                    result["msg"] = "Unsupported mode for policy."
                else:
                    rssh, sshstr = ssh_and_configure(
                        login, password, fos_ip_addr, ssh_hostkeymust,
                        "dlsset --disable -lossless", "Lossless is not set")
                    if rssh != 0:
                        result["failed"] = True
                        result[
                            "msg"] = "Failed to disable DLS lossless. " + sshstr
                    else:
                        rssh, sshstr = ssh_and_configure(
                            login, password, fos_ip_addr, ssh_hostkeymust,
                            "dlsset --disable -twohop",
                            "Two-hop lossless is not set")
                        if rssh != 0:
                            result["failed"] = True
                            result[
                                "msg"] = "Failed to disable DLS twohop. " + sshstr
                        else:
                            rssh, sshstr = ssh_and_configure(
                                login, password, fos_ip_addr, ssh_hostkeymust,
                                "dlsreset", "DLS is not set")
                            if rssh != 0:
                                result["failed"] = True
                                result["msg"] = "Failed to reset. " + sshstr
                            else:
                                result["changed"] = True
            elif l_diffs["dynamic-load-sharing"] == "lossless-dls":
                rssh, sshstr = ssh_and_configure(
                    login, password, fos_ip_addr, ssh_hostkeymust,
                    "dlsset --enable -lossless",
                    ["Lossless is set", "DLS and Lossless are set"])
                if rssh != 0:
                    result["failed"] = True
                    result["msg"] = "Failed to enable DLS lossless. " + sshstr
                else:
                    rssh, sshstr = ssh_and_configure(
                        login, password, fos_ip_addr, ssh_hostkeymust,
                        "dlsset --disable -twohop", [
                            "Two-hop lossless disabled successfully",
                            "Two-hop lossless is not set"
                        ])
                    if rssh != 0:
                        result["failed"] = True
                        result[
                            "msg"] = "Failed to disable DLS twohop. " + sshstr
                    else:
                        result["changed"] = True
                        result["messages"] = "disabled DSL twohop"
            elif l_diffs["dynamic-load-sharing"] == "two-hop-lossless-dls":
                rssh, sshstr = ssh_and_configure(
                    login, password, fos_ip_addr, ssh_hostkeymust,
                    "dlsset --enable -lossless",
                    ["Lossless is set", "DLS and Lossless are set"])
                if rssh != 0:
                    result["failed"] = True
                    result["msg"] = "Failed to enable DLS lossless. " + sshstr
                else:
                    rssh, sshstr = ssh_and_configure(
                        login, password, fos_ip_addr, ssh_hostkeymust,
                        "dlsset --enable -twohop",
                        "Two-hop lossless enabled successfully")
                    if rssh != 0:
                        result["failed"] = True
                        result[
                            "msg"] = "Failed to enable DLS twohop. " + sshstr
                    else:
                        result["changed"] = True
                        result["messages"] = "enable DSL two-hop-lossless-dls"
            elif l_diffs["dynamic-load-sharing"] == "dls":
                if in_mode_3:
                    rssh, sshstr = ssh_and_configure(
                        login, password, fos_ip_addr, ssh_hostkeymust,
                        "dlsset --disable -lossless", "Lossless is not set")
                    if rssh != 0:
                        result["failed"] = True
                        result["msg"] = "Failed to dlsset. " + sshstr
                    else:
                        result["changed"] = True
                        result["messages"] = "enable DSL dls"
                else:
                    rssh, sshstr = ssh_and_configure(login, password,
                                                     fos_ip_addr,
                                                     ssh_hostkeymust,
                                                     "dlsreset",
                                                     "DLS is not set")
                    if rssh != 0:
                        result["failed"] = True
                        result["msg"] = "Failed to dlsreset. " + sshstr
                    else:
                        rssh, sshstr = ssh_and_configure(
                            login, password, fos_ip_addr, ssh_hostkeymust,
                            "dlsset", "DLS is set")
                        if rssh != 0:
                            result["failed"] = True
                            result["msg"] = "Failed to dlsset. " + sshstr
                        else:
                            result["changed"] = True
                            result["messages"] = "enable DSL dls"
            else:
                result["failed"] = True
                result["msg"] = "Unkown DLS mode"
            l_diffs.pop("dynamic-load-sharing")

    # should be only key for the switch if nothing else
    if len(l_diffs) <= 1:
        return 0

    full_fc_switch_url, validate_certs = full_url_get(is_https, fos_ip_addr,
                                                      REST_SWITCH)

    return (url_patch_single_object(fos_ip_addr, is_https, auth, vfid, result,
                                    full_fc_switch_url, "fibrechannel-switch",
                                    l_diffs, timeout))