WARNING: THIS SITE IS A MIRROR OF GITHUB.COM / IT CANNOT LOGIN OR REGISTER ACCOUNTS / THE CONTENTS ARE PROVIDED AS-IS / THIS SITE ASSUMES NO RESPONSIBILITY FOR ANY DISPLAYED CONTENT OR LINKS / IF YOU FOUND SOMETHING MAY NOT GOOD FOR EVERYONE, CONTACT ADMIN AT ilovescratch@foxmail.com
Skip to content

Commit 33cb7ad

Browse files
committed
fix(sshx): add SFTP connection
1 parent f3231ea commit 33cb7ad

File tree

7 files changed

+103
-22
lines changed

7 files changed

+103
-22
lines changed

examples/ssh-proxy.yml

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
# Version may either be a specific k3s version or a release channel
2+
# as listed here: https://update.k3s.io/v1-release/channels
3+
version: stable
4+
5+
# Cluster provides cluster-wide settings that should be applied
6+
# to all nodes in the cluster. All options are equivalent to the
7+
# commmand line options of the `k3s` command.
8+
cluster:
9+
tls-san:
10+
- kubeapi.example.com
11+
disable:
12+
- traefik
13+
write-kubeconfig-mode: "644"
14+
15+
# A list of all nodes in the cluster and their connection information.
16+
nodes:
17+
- role: server
18+
ssh:
19+
host: 127.0.0.1
20+
fingerprint: SHA256:t/bwWCelgcAEYmQW9XbM4p31e1Qq70ZPWOKK+FRxBCc
21+
user: nicklasfrahm
22+
key-file: ~/.ssh/id_ed25519
23+
config:
24+
node-label:
25+
- cpu=i3-7100
26+
27+
# An SSH proxy, also known as jumpbox or a bastion host
28+
# can be used to access nodes in a private network.
29+
ssh-proxy:
30+
host: tph99.nicklasfrahm.xyz
31+
fingerprint: SHA256:t/bwWCelgcAEYmQW9XbM4p31e1Qq70ZPWOKK+FRxBCc
32+
user: nicklasfrahm
33+
key-file: ~/.ssh/id_ed25519

examples/standalone.yml

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -16,17 +16,10 @@ cluster:
1616
nodes:
1717
- role: server
1818
ssh:
19-
host: 127.0.0.1
19+
host: tph99.nicklasfrahm.xyz
2020
fingerprint: SHA256:t/bwWCelgcAEYmQW9XbM4p31e1Qq70ZPWOKK+FRxBCc
2121
user: nicklasfrahm
2222
key-file: ~/.ssh/id_ed25519
23-
node-label:
24-
- cpu=i3-7100
25-
26-
# An SSH proxy, also known as jumpbox or a bastion host
27-
# can be used to access nodes in a private network.
28-
ssh-proxy:
29-
host: tph99.nicklasfrahm.xyz
30-
fingerprint: SHA256:t/bwWCelgcAEYmQW9XbM4p31e1Qq70ZPWOKK+FRxBCc
31-
user: nicklasfrahm
32-
key-file: ~/.ssh/id_ed25519
23+
config:
24+
node-label:
25+
- cpu=i3-7100

go.mod

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ module github.com/nicklasfrahm/k3se
33
go 1.17
44

55
require (
6+
github.com/pkg/sftp v1.13.4
67
github.com/rs/zerolog v1.26.1
78
github.com/spf13/cobra v1.4.0
89
golang.org/x/crypto v0.0.0-20220408190544-5352b0902921
@@ -11,6 +12,7 @@ require (
1112

1213
require (
1314
github.com/inconshreveable/mousetrap v1.0.0 // indirect
15+
github.com/kr/fs v0.1.0 // indirect
1416
github.com/spf13/pflag v1.0.5 // indirect
1517
golang.org/x/sys v0.0.0-20211210111614-af8b64212486 // indirect
1618
)

go.sum

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,17 @@
11
github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
22
github.com/cpuguy83/go-md2man/v2 v2.0.1/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
3+
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
4+
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
35
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
46
github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM=
57
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
8+
github.com/kr/fs v0.1.0 h1:Jskdu9ieNAYnjxsi0LbQp1ulIKZV1LAFgK1tWhpZgl8=
9+
github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg=
610
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
11+
github.com/pkg/sftp v1.13.4 h1:Lb0RYJCmgUcBgZosfoi9Y9sbl6+LJgOIgk/2Y4YjMFg=
12+
github.com/pkg/sftp v1.13.4/go.mod h1:LzqnAvaD5TWeNBsZpfKxSYn1MbjWwOsCIAFFJbpIsK8=
13+
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
14+
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
715
github.com/rs/xid v1.3.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg=
816
github.com/rs/zerolog v1.26.1 h1:/ihwxqH+4z8UxyI70wM1z9yCvkWcfz/a3mj48k/Zngc=
917
github.com/rs/zerolog v1.26.1/go.mod h1:/wSSJWX7lVrsOwlbyTRSOJvqRlc+WjWlfes+CiJ+tmc=
@@ -12,9 +20,13 @@ github.com/spf13/cobra v1.4.0 h1:y+wJpx64xcgO1V+RcnwW0LEHxTKRi2ZDPSBjWnrg88Q=
1220
github.com/spf13/cobra v1.4.0/go.mod h1:Wo4iy3BUC+X2Fybo0PDqwJIv3dNRiZLHQymsfxlB84g=
1321
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
1422
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
23+
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
24+
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
25+
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
1526
github.com/yuin/goldmark v1.4.0/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
1627
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
1728
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
29+
golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
1830
golang.org/x/crypto v0.0.0-20211215165025-cf75a172585e/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8=
1931
golang.org/x/crypto v0.0.0-20220408190544-5352b0902921 h1:iU7T1X1J6yxDr0rda54sWGkHgOp5XJrqm79gcNlC2VM=
2032
golang.org/x/crypto v0.0.0-20220408190544-5352b0902921/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
@@ -23,12 +35,15 @@ golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn
2335
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
2436
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
2537
golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
38+
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
2639
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
2740
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
2841
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
2942
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
3043
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
3144
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
45+
golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
46+
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
3247
golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
3348
golang.org/x/sys v0.0.0-20211210111614-af8b64212486 h1:5hpz5aRr+W1erYCL5JRhSUBJRph7l9XkNveoExlrKYk=
3449
golang.org/x/sys v0.0.0-20211210111614-af8b64212486/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
@@ -46,5 +61,6 @@ golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8T
4661
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
4762
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
4863
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
64+
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
4965
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo=
5066
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

pkg/engine/node.go

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
package engine
22

3-
import "github.com/nicklasfrahm/k3se/pkg/sshx"
3+
import (
4+
"github.com/nicklasfrahm/k3se/pkg/sshx"
5+
)
46

57
const (
68
// Program is used to configure the name of the configuration file.
@@ -9,11 +11,11 @@ const (
911

1012
// Node describes the configuration of a node.
1113
type Node struct {
12-
Role Role `yaml:"role"`
13-
SSH sshx.Config `yaml:"ssh"`
14-
NodeLabel []string `yaml:"node-label"`
14+
Role Role `yaml:"role"`
15+
SSH sshx.Config `yaml:"ssh"`
16+
Config K3sConfig `yaml:"config"`
1517

16-
*sshx.Client `yaml:"-"`
18+
Client *sshx.Client `yaml:"-"`
1719
}
1820

1921
// Connect establishes a connection to the node.
@@ -37,5 +39,9 @@ func (node *Node) Connect(options ...Option) error {
3739

3840
// Disconnect closes the connection to the node.
3941
func (node *Node) Disconnect() error {
42+
if node.Client != nil {
43+
return node.Client.Close()
44+
}
45+
4046
return nil
4147
}

pkg/ops/up.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,12 @@ func Up(options ...Option) error {
4646
// TODO: Copy kubeconfig to /etc/rancher/k3s/k3s.yaml.
4747

4848
// TODO: Store state on server nodes to allow for configuration diffing later on.
49+
// TODO: Fetch state from Git history.
50+
51+
// Disconnect from all nodes.
52+
for _, node := range nodes {
53+
node.Disconnect()
54+
}
4955

5056
return nil
5157
}

pkg/sshx/client.go

Lines changed: 31 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import (
77
"net"
88
"os/user"
99

10+
"github.com/pkg/sftp"
1011
"golang.org/x/crypto/ssh"
1112
)
1213

@@ -25,11 +26,13 @@ type Config struct {
2526
// Client is an augmented SSH client.
2627
type Client struct {
2728
*Options
28-
*ssh.Client
29+
30+
SSH *ssh.Client
31+
SFTP *sftp.Client
2932
}
3033

31-
// NewClient creates a new SSH client based on an SSH configuration
32-
// and connects to it.
34+
// NewClient creates a new SSH client and a new SFTP client based
35+
// on an SSH configuration and connects to it.
3336
func NewClient(config *Config, options ...Option) (*Client, error) {
3437
opts, err := GetDefaultOptions().Apply(options...)
3538
if err != nil {
@@ -57,7 +60,7 @@ func NewClient(config *Config, options ...Option) (*Client, error) {
5760

5861
if client.Proxy != nil {
5962
// Create a TCP connection from the proxy host to the target.
60-
netConn, err := client.Proxy.Client.Dial("tcp", address)
63+
netConn, err := client.Proxy.SSH.Dial("tcp", address)
6164
if err != nil {
6265
return nil, err
6366
}
@@ -67,9 +70,12 @@ func NewClient(config *Config, options ...Option) (*Client, error) {
6770
return nil, err
6871
}
6972

70-
client.Client = ssh.NewClient(targetConn, channel, req)
73+
client.SSH = ssh.NewClient(targetConn, channel, req)
7174
} else {
72-
if client.Client, err = ssh.Dial("tcp", address, normalizedConfig); err != nil {
75+
if client.SSH, err = ssh.Dial("tcp", address, normalizedConfig); err != nil {
76+
return nil, err
77+
}
78+
if client.SFTP, err = sftp.NewClient(client.SSH); err != nil {
7379
return nil, err
7480
}
7581
}
@@ -152,3 +158,22 @@ func (client *Client) normalizeConfig(config *Config) (*ssh.ClientConfig, error)
152158
Timeout: client.Timeout,
153159
}, nil
154160
}
161+
162+
// Close closes the SFTP connection first as it
163+
// piggy-backs on the SSH connection. After that
164+
// the SSH connection of the client is closed.
165+
func (client *Client) Close() error {
166+
if client.SFTP != nil {
167+
if err := client.SFTP.Close(); err != nil {
168+
return err
169+
}
170+
}
171+
172+
if client.SSH != nil {
173+
if err := client.SSH.Close(); err != nil {
174+
return err
175+
}
176+
}
177+
178+
return nil
179+
}

0 commit comments

Comments
 (0)