(connCtx context.Context, opts *SSHOpts, currentClient *ssh.Client, jumpNum int32, connFlags *wconfig.ConnKeywords)
| 869 | } |
| 870 | |
| 871 | func ConnectToClient(connCtx context.Context, opts *SSHOpts, currentClient *ssh.Client, jumpNum int32, connFlags *wconfig.ConnKeywords) (*ssh.Client, int32, error) { |
| 872 | blocklogger.Infof(connCtx, "[conndebug] ConnectToClient %s (jump:%d)...\n", opts.String(), jumpNum) |
| 873 | debugInfo := &ConnectionDebugInfo{ |
| 874 | CurrentClient: currentClient, |
| 875 | NextOpts: opts, |
| 876 | JumpNum: jumpNum, |
| 877 | } |
| 878 | if jumpNum > SshProxyJumpMaxDepth { |
| 879 | return nil, jumpNum, ConnectionError{ConnectionDebugInfo: debugInfo, Err: utilds.Errorf(ConnErrCode_ProxyDepth, "ProxyJump %d exceeds Wave's max depth of %d", jumpNum, SshProxyJumpMaxDepth)} |
| 880 | } |
| 881 | |
| 882 | rawName := opts.String() |
| 883 | fullConfig := wconfig.GetWatcher().GetFullConfig() |
| 884 | internalSshConfigKeywords, ok := fullConfig.Connections[rawName] |
| 885 | if !ok { |
| 886 | internalSshConfigKeywords = wconfig.ConnKeywords{} |
| 887 | } |
| 888 | |
| 889 | var sshConfigKeywords *wconfig.ConnKeywords |
| 890 | if utilfn.SafeDeref(internalSshConfigKeywords.ConnIgnoreSshConfig) { |
| 891 | var err error |
| 892 | sshConfigKeywords, err = findSshDefaults(opts.SSHHost) |
| 893 | if err != nil { |
| 894 | err = utilds.MakeCodedError(ConnErrCode_ConfigDefault, fmt.Errorf("cannot determine default config keywords: %w", err)) |
| 895 | return nil, debugInfo.JumpNum, ConnectionError{ConnectionDebugInfo: debugInfo, Err: err} |
| 896 | } |
| 897 | } else { |
| 898 | var err error |
| 899 | sshConfigKeywords, err = findSshConfigKeywords(opts.SSHHost) |
| 900 | if err != nil { |
| 901 | err = utilds.MakeCodedError(ConnErrCode_ConfigParse, fmt.Errorf("cannot determine config keywords: %w", err)) |
| 902 | return nil, debugInfo.JumpNum, ConnectionError{ConnectionDebugInfo: debugInfo, Err: err} |
| 903 | } |
| 904 | } |
| 905 | |
| 906 | parsedKeywords := &wconfig.ConnKeywords{} |
| 907 | if opts.SSHUser != "" { |
| 908 | parsedKeywords.SshUser = &opts.SSHUser |
| 909 | } |
| 910 | if opts.SSHPort != "" { |
| 911 | parsedKeywords.SshPort = &opts.SSHPort |
| 912 | } |
| 913 | |
| 914 | // cascade order: |
| 915 | // ssh config -> (optional) internal config -> specified flag keywords -> parsed keywords |
| 916 | partialMerged := sshConfigKeywords |
| 917 | partialMerged = mergeKeywords(partialMerged, &internalSshConfigKeywords) |
| 918 | partialMerged = mergeKeywords(partialMerged, connFlags) |
| 919 | sshKeywords := mergeKeywords(partialMerged, parsedKeywords) |
| 920 | |
| 921 | // handle these separately since |
| 922 | // - they append |
| 923 | // - since they append, the order is reversed |
| 924 | // - there is no reason to not include the internal config |
| 925 | // - they are never part of the parsedKeywords |
| 926 | sshKeywords.SshIdentityFile = append(sshKeywords.SshIdentityFile, connFlags.SshIdentityFile...) |
| 927 | sshKeywords.SshIdentityFile = append(sshKeywords.SshIdentityFile, internalSshConfigKeywords.SshIdentityFile...) |
| 928 | sshKeywords.SshIdentityFile = append(sshKeywords.SshIdentityFile, sshConfigKeywords.SshIdentityFile...) |
no test coverage detected