diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml index 140b757b..c3885aa5 100644 --- a/.github/workflows/go.yml +++ b/.github/workflows/go.yml @@ -108,6 +108,36 @@ jobs: env: LINUX_IMAGE: ${{ matrix.image }} run: make smoke-basic + + smoke-basic: + strategy: + matrix: + image: + - quay.io/k0sproject/bootloose-alpine3.18 + name: Basic 1+1 smoke using openssh client + needs: build + runs-on: ubuntu-20.04 + + steps: + - uses: actions/checkout@v4 + - name: Set up Go + uses: actions/setup-go@v4 + with: + go-version-file: go.mod + check-latest: true + + - {"name":"Go modules cache","uses":"actions/cache@v3","with":{"path":"~/go/pkg/mod\n~/.cache/go-build\n~/Library/Caches/go-build\n%LocalAppData%\\go-build\n","key":"${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}","restore-keys":"${{ runner.os }}-go-\n"}} + - {"name":"Compiled binary cache","uses":"actions/download-artifact@v3","with":{"name":"k0sctl","path":"."}} + - {"name":"Make executable","run":"chmod +x k0sctl"} + - {"name":"K0sctl cache","uses":"actions/cache@v3","with":{"path":"/var/cache/k0sctl\n~/.cache/k0sctl\n!*.log\n","key":"k0sctl-cache"}} + - {"name":"Kubectl cache","uses":"actions/cache@v3","with":{"path":"smoke-test/kubectl\n","key":"kubectl-1.21.3"}} + - {"name":"Go modules cache","uses":"actions/cache@v3","with":{"path":"~/go/pkg/mod\n~/.cache/go-build\n~/Library/Caches/go-build\n%LocalAppData%\\go-build\n","key":"${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}","restore-keys":"${{ runner.os }}-go-\n"}} + - {"name":"Docker Layer Caching For Bootloose","uses":"satackey/action-docker-layer-caching@v0.0.11","continue-on-error":true} + + - name: Run smoke tests + env: + LINUX_IMAGE: ${{ matrix.image }} + run: make smoke-basic-openssh smoke-files: strategy: diff --git a/README.md b/README.md index b4831d9a..3e02e145 100644 --- a/README.md +++ b/README.md @@ -468,7 +468,7 @@ IP address of the host Username to log in as. -###### `spec.hosts[*].ssh.port` <string> (required) +###### `spec.hosts[*].ssh.port` <number> (required) TCP port of the SSH service on the host. @@ -484,6 +484,83 @@ Localhost connection options. Can be used to use the local host running k0sctl a This must be set `true` to enable the localhost connection. +##### `spec.hosts[*].openSSH` <mapping> (optional) + +An alternative SSH client protocol that uses the system's openssh client for connections. + +Example: + +```yaml +spec: + hosts: + - role: controller + openSSH: + address: 10.0.0.2 +``` + +The only required field is the `address` and it can also be a hostname that is found in the ssh config. All other options such as user, port and keypath will use the same defaults as if running `ssh` from the command-line or will use values found from the ssh config. + +An example SSH config: + +``` +Host controller1 + Hostname 10.0.0.1 + Port 2222 + IdentityFile ~/.ssh/id_cluster_esa +``` + +If this is in your `~/.ssh/config`, you can simply use the host alias as the address in your k0sctl config: + +```yaml +spec: + hosts: + - role: controller + openSSH: + address: controller1 + # if the ssh configuration is in a different file, you can use: + # configPath: /path/to/config +``` + +###### `spec.hosts[*].ssh.address` <string> (required) + +IP address, hostname or ssh config host alias of the host + +###### `spec.hosts[*].openSSH.user` <string> (optional) + +Username to connect as. + +###### `spec.hosts[*].openSSH.port` <number> (optional) + +Remote port. + +###### `spec.hosts[*].openSSH.keyPath` <string> (optional) + +Path to private key. + +###### `spec.hosts[*].openSSH.configPath` <string> (optional) + +Path to ssh config, defaults to ~/.ssh/config with fallback to /etc/ssh/ssh_config. + +###### `spec.hosts[*].openSSH.disableMultiplexing` <boolean> (optional) + +The default mode of operation is to use connection multiplexing where a ControlMaster connection is opened and the subsequent connections to the same host use the master connection over a socket to communicate to the host. + +If this is disabled by setting `disableMultiplexing: true`, running every remote command will require reconnecting and reauthenticating to the host. + +###### `spec.hosts[*].openSSH.options` <mapping> (optional) + +Additional options as key/value pairs to use when running the ssh client. + +Example: + +```yaml +openSSH: + address: host + options: + ForwardAgent: true # -o ForwardAgent=yes + StrictHostkeyChecking: false # -o StrictHostkeyChecking: no +``` + ###### `spec.hosts[*].reset` <boolean> (optional) (default: `false`) If set to `true` k0sctl will remove the node from kubernetes and reset k0s on the host. diff --git a/go.mod b/go.mod index b4ca083c..ff941f32 100644 --- a/go.mod +++ b/go.mod @@ -16,7 +16,7 @@ require ( github.com/gofrs/uuid v4.4.0+incompatible // indirect github.com/hashicorp/go-version v1.6.0 // indirect github.com/k0sproject/dig v0.2.0 - github.com/k0sproject/rig v0.14.0 + github.com/k0sproject/rig v0.15.1 github.com/logrusorgru/aurora v2.0.3+incompatible github.com/masterzen/simplexml v0.0.0-20190410153822-31eea3082786 // indirect github.com/masterzen/winrm v0.0.0-20220917170901-b07f6cb0598d // indirect @@ -28,10 +28,10 @@ require ( github.com/stretchr/testify v1.8.4 github.com/urfave/cli/v2 v2.25.7 github.com/xtgo/uuid v0.0.0-20140804021211-a0b114877d4c // indirect - golang.org/x/crypto v0.13.0 // indirect + golang.org/x/crypto v0.14.0 // indirect golang.org/x/net v0.13.0 // indirect - golang.org/x/sys v0.12.0 // indirect - golang.org/x/term v0.12.0 // indirect + golang.org/x/sys v0.13.0 // indirect + golang.org/x/term v0.13.0 // indirect golang.org/x/text v0.13.0 gopkg.in/yaml.v2 v2.4.0 k8s.io/client-go v0.28.2 diff --git a/go.sum b/go.sum index 0f02ee4a..23056244 100644 --- a/go.sum +++ b/go.sum @@ -121,8 +121,8 @@ github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnr github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/k0sproject/dig v0.2.0 h1:cNxEIl96g9kqSMfPSZLhpnZ0P8bWXKv08nxvsMHop5w= github.com/k0sproject/dig v0.2.0/go.mod h1:rBcqaQlJpcKdt2x/OE/lPvhGU50u/e95CSm5g/r4s78= -github.com/k0sproject/rig v0.14.0 h1:DqmSZTuv9Ae6WQEQwLscxcvn6EnCrwWz5/azgP7Km1c= -github.com/k0sproject/rig v0.14.0/go.mod h1:1niIomLJnggPcnduA1HfmdWYvxe+N5xABQ+1DjX+nsA= +github.com/k0sproject/rig v0.15.1 h1:QjEBSgDDMk24NB6vLozIilUGPn0nOGEz/AFkPOZkYWw= +github.com/k0sproject/rig v0.15.1/go.mod h1:EQQjrgGbRY6MpbuZRpzMaymJJ86RJVxIuGsPGsVNfZg= github.com/k0sproject/version v0.4.2 h1:zrbT5xRv1ai4N102ZaHTTq9Zqf6pAGFm9WCxHaC9QHY= github.com/k0sproject/version v0.4.2/go.mod h1:oEjuz2ItQQtAnGyRgwEV9m5R6/9rjoFC6EiEEzbkFdI= github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 h1:Z9n2FFNUXsshfwJMBgNA0RU6/i7WVaAegv3PtuIHPMs= @@ -214,8 +214,8 @@ golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a/go.mod h1:P+XmwS30IXTQdn5 golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58= -golang.org/x/crypto v0.13.0 h1:mvySKfSWJ+UKUii46M40LOvyWfN0s2U+46/jDd0e6Ck= -golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc= +golang.org/x/crypto v0.14.0 h1:wBqGXzWJW6m1XrIKlAH0Hs1JJ7+9KBwnIO8v66Q9cHc= +golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= @@ -257,13 +257,13 @@ golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.12.0 h1:CM0HF96J0hcLAwsHPJZjfdNzs0gftsLfgKt57wWHJ0o= -golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE= +golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= -golang.org/x/term v0.12.0 h1:/ZfYdc3zq+q02Rv9vGqTeSItdzZTSNDmfTi0mBAuidU= -golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU= +golang.org/x/term v0.13.0 h1:bb+I9cTfFazGW51MZqBVmZy7+JEJMouUHTUSKVQLBek= +golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= diff --git a/smoke-test/Makefile b/smoke-test/Makefile index 83a189e2..098038bb 100644 --- a/smoke-test/Makefile +++ b/smoke-test/Makefile @@ -22,6 +22,9 @@ id_rsa_k0s: smoke-basic: $(bootloose) id_rsa_k0s k0sctl ./smoke-basic.sh +smoke-basic-openssh: $(bootloose) id_rsa_k0s k0sctl + ./smoke-basic-openssh.sh + smoke-dynamic: $(bootloose) id_rsa_k0s k0sctl ./smoke-dynamic.sh @@ -42,3 +45,4 @@ smoke-os-override: $(bootloose) id_rsa_k0s k0sctl smoke-backup-restore: $(bootloose) id_rsa_k0s k0sctl ./smoke-backup-restore.sh + diff --git a/smoke-test/k0sctl-openssh.yaml b/smoke-test/k0sctl-openssh.yaml new file mode 100644 index 00000000..81ea3e74 --- /dev/null +++ b/smoke-test/k0sctl-openssh.yaml @@ -0,0 +1,21 @@ +apiVersion: k0sctl.k0sproject.io/v1beta1 +kind: cluster +spec: + hosts: + - role: controller + uploadBinary: true + openSSH: + address: controller + configPath: ssh/config + - role: worker + uploadBinary: true + openSSH: + address: worker + port: 9023 + configPath: ssh/config + k0s: + version: "${K0S_VERSION}" + config: + spec: + telemetry: + enabled: false diff --git a/smoke-test/smoke-basic-openssh.sh b/smoke-test/smoke-basic-openssh.sh new file mode 100755 index 00000000..c30f3680 --- /dev/null +++ b/smoke-test/smoke-basic-openssh.sh @@ -0,0 +1,38 @@ +#!/usr/bin/env sh + +K0SCTL_CONFIG=${K0SCTL_CONFIG:-"k0sctl-openssh.yaml"} + +set -e + +. ./smoke.common.sh +trap cleanup_openssh EXIT + +cleanup_openssh() { + cleanup + [ -f "ssh/id_rsa_k0s" ] && rm -rf .ssh +} + +deleteCluster +createCluster + +echo "* Create SSH config" +mkdir -p ssh +cp id_rsa_k0s ssh/ +cat < ssh/config +Host * + StrictHostKeyChecking no + UserKnownHostsFile /dev/null + IdentityFile id_rsa_k0s + User root +Host controller + Hostname 127.0.0.1 + Port 9022 +Host worker + Hostname 127.0.0.1 + Port 9023 +EOF + +echo "* Starting apply" +../k0sctl apply --config "${K0SCTL_CONFIG}" --debug +echo "* Apply OK" +