Skip to content

Commit 8e1fb78

Browse files
Merge pull request #61 from misha-ssh/33-create-logic-cp
33 create logic cp
2 parents 3b6f100 + a65418d commit 8e1fb78

36 files changed

Lines changed: 977 additions & 355 deletions

.coverage.yml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,7 @@ exclude:
77
paths:
88
- ^examples
99
- ^pkg/connect/ssh.go
10-
- ^pkg/kernel/connect.go
10+
- ^pkg/connect/sftp.go
11+
- ^pkg/kernel/connect.go
12+
- ^pkg/kernel/download.go
13+
- ^pkg/kernel/upload.go
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
name: Tests Integration
2+
3+
on:
4+
push:
5+
branches: [ main ]
6+
pull_request:
7+
branches: [ main ]
8+
9+
jobs:
10+
tests:
11+
name: Test Integration on Ubuntu latest
12+
runs-on: ubuntu-latest
13+
container:
14+
image: ubuntu:latest
15+
options: --privileged
16+
env:
17+
DEBIAN_FRONTEND: noninteractive
18+
steps:
19+
- uses: actions/checkout@v4
20+
- name: Setup Go
21+
uses: actions/setup-go@v5
22+
with:
23+
go-version-file: "go.mod"
24+
25+
- name: Install Dependencies
26+
run: |
27+
apt-get update
28+
apt-get install -y gnome-keyring build-essential ca-certificates openssh-client
29+
mkdir -p /github/home/.cache/
30+
mkdir -p /github/home/.local/share/keyrings/
31+
chmod 700 -R /github/home/.local/
32+
33+
- name: Get dependencies
34+
run: |
35+
go get -v -t -d ./...
36+
37+
- name: Tests integration
38+
run: |
39+
echo 'somecredstorepass' | gnome-keyring-daemon --unlock
40+
make tests-integration
41+
42+
shell: dbus-run-session -- bash --noprofile --norc -eo pipefail {0}

Makefile

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -52,10 +52,15 @@ lint:
5252

5353
# use tests for check tests cases
5454
tests:
55-
GO_TESTING=true go test -v ./... -timeout 10s
55+
GO_TESTING=true go test -tags=unit -v ./...
5656

5757
# use test-coverage for verify coverage
5858
test-coverage:
5959
go install github.com/vladopajic/go-test-coverage/v2@latest
60-
go test ./... -coverprofile=./cover.out -covermode=atomic -coverpkg=./... \
61-
&& go-test-coverage --config=./.coverage.yml
60+
GO_TESTING=true go test -tags=unit ./... -coverprofile=./cover.out -covermode=atomic -coverpkg=./... \
61+
&& go-test-coverage --config=./.coverage.yml
62+
63+
# use tests-integration for check integration tests cases
64+
# You need an installed docker to work
65+
tests-integration:
66+
GO_TESTING=true go test -tags=integration ./...

README.md

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
[![Release](https://img.shields.io/github/release/misha-ssh/kernel?status.svg)](https://github.com/misha-ssh/kernel/releases)
66
[![Action Lint](https://github.com/misha-ssh/kernel/actions/workflows/lint.yml/badge.svg)](https://github.com/misha-ssh/kernel)
77
[![Action Tests](https://github.com/misha-ssh/kernel/actions/workflows/tests.yml/badge.svg)](https://github.com/misha-ssh/kernel)
8+
[![Action Tests Integration](https://github.com/misha-ssh/kernel/actions/workflows/tests-integration.yml/badge.svg)](https://github.com/misha-ssh/kernel)
89

910
This package acts as the core for an ssh client written in go
1011

@@ -17,6 +18,7 @@ Made using data from packages:
1718
## 📝 Features
1819

1920
- **Connection Management:** Commands for creating, connecting, deleting, and updating your connection
21+
- **Download & Upload files:** Commands for working with sftp file transfer
2022
- **Data encryption:** Your connection is securely encrypted
2123
- **Configurations:** Possibility of connection configuration
2224
- **The local environment** There is an environment for testing the connection
@@ -58,6 +60,62 @@ func main() {
5860
}
5961
```
6062

63+
### 🔌 Download
64+
65+
The command to connect to the remote server
66+
67+
this command downloads the file from the server
68+
69+
```go
70+
package main
71+
72+
import (
73+
"github.com/misha-ssh/kernel/pkg/connect"
74+
"github.com/misha-ssh/kernel/pkg/kernel"
75+
)
76+
77+
func main() {
78+
connection := &connect.Connect{...}
79+
80+
remoteFile := "/remote.txt"
81+
localFile := "~/local.txt"
82+
83+
err := kernel.Download(connection, remoteFile, localFile)
84+
if err != nil {
85+
panic(err)
86+
}
87+
}
88+
89+
```
90+
91+
### 🔌 Upload
92+
93+
The command to connect to the remote server
94+
95+
this command is to upload a file to a remote server
96+
97+
```go
98+
package main
99+
100+
import (
101+
"github.com/misha-ssh/kernel/pkg/connect"
102+
"github.com/misha-ssh/kernel/pkg/kernel"
103+
)
104+
105+
func main() {
106+
connection := &connect.Connect{...}
107+
108+
remoteFile := "/upload.txt"
109+
localFile := "/absolute/path/your_local_file.txt"
110+
111+
err := kernel.Upload(connection, localFile, remoteFile)
112+
if err != nil {
113+
panic(err)
114+
}
115+
}
116+
117+
```
118+
61119
### ✍️ Create
62120

63121
The command to create a connection

build/ssh/default/Dockerfile

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,6 @@ RUN echo "root:password" | chpasswd
88

99
RUN echo 'PermitRootLogin yes' >> /etc/ssh/sshd_config
1010

11+
RUN echo 'text in remote file' > remote.txt
12+
1113
CMD ["/usr/sbin/sshd", "-D"]

e2e/kernel/connect_test.go

Lines changed: 156 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,156 @@
1+
//go:build integration
2+
3+
package kernel
4+
5+
import (
6+
"context"
7+
"os/exec"
8+
"testing"
9+
"time"
10+
11+
"github.com/misha-ssh/kernel/internal/storage"
12+
"github.com/misha-ssh/kernel/pkg/connect"
13+
"github.com/stretchr/testify/require"
14+
"github.com/testcontainers/testcontainers-go"
15+
"github.com/testcontainers/testcontainers-go/wait"
16+
"golang.org/x/crypto/ssh"
17+
)
18+
19+
func TestIntegrationDefaultConnect(t *testing.T) {
20+
ctx := context.Background()
21+
22+
req := testcontainers.ContainerRequest{
23+
FromDockerfile: testcontainers.FromDockerfile{
24+
Context: "../../build/ssh/default",
25+
Dockerfile: "Dockerfile",
26+
},
27+
ExposedPorts: []string{"22/tcp"},
28+
WaitingFor: wait.ForListeningPort("22/tcp").WithStartupTimeout(30 * time.Second),
29+
}
30+
31+
c, err := testcontainers.GenericContainer(ctx, testcontainers.GenericContainerRequest{
32+
ContainerRequest: req,
33+
Started: true,
34+
})
35+
if err != nil {
36+
t.Fatal(err)
37+
}
38+
defer func() {
39+
if err := c.Terminate(ctx); err != nil {
40+
t.Logf("failed to terminate container: %s", err)
41+
}
42+
}()
43+
44+
host, err := c.Host(ctx)
45+
if err != nil {
46+
t.Fatal(err)
47+
}
48+
49+
port, err := c.MappedPort(ctx, "22/tcp")
50+
if err != nil {
51+
t.Fatal(err)
52+
}
53+
54+
if c.IsRunning() {
55+
connection := &connect.Connect{
56+
Alias: "test",
57+
Login: "root",
58+
Password: "password",
59+
Address: host,
60+
Type: connect.TypeSSH,
61+
CreatedAt: "",
62+
UpdatedAt: "",
63+
SshOptions: &connect.SshOptions{
64+
Port: port.Int(),
65+
PrivateKey: "",
66+
},
67+
}
68+
69+
sshConnector := &connect.Ssh{}
70+
session, err := sshConnector.Session(connection)
71+
if err != nil {
72+
t.Fatal(err)
73+
}
74+
75+
defer func(session *ssh.Session) {
76+
err := session.Close()
77+
if err != nil {
78+
t.Fatal(err)
79+
}
80+
}(session)
81+
82+
err = session.Shell()
83+
if err != nil {
84+
t.Fatal(err)
85+
}
86+
}
87+
}
88+
89+
func TestIntegrationPrivateKeyConnect(t *testing.T) {
90+
sshKeysName := "../../build/ssh/key/dockerkey"
91+
92+
if !storage.Exists(storage.GetDirectionAndFilename(sshKeysName)) {
93+
cmdKey := exec.Command("ssh-keygen", "-b", "4096", "-t", "rsa", "-f", sshKeysName)
94+
require.NoError(t, cmdKey.Run())
95+
}
96+
97+
ctx := context.Background()
98+
99+
req := testcontainers.ContainerRequest{
100+
FromDockerfile: testcontainers.FromDockerfile{
101+
Context: "../../build/ssh/key",
102+
Dockerfile: "Dockerfile",
103+
},
104+
ExposedPorts: []string{"22/tcp"},
105+
WaitingFor: wait.ForListeningPort("22/tcp").WithStartupTimeout(30 * time.Second),
106+
}
107+
108+
c, err := testcontainers.GenericContainer(ctx, testcontainers.GenericContainerRequest{
109+
ContainerRequest: req,
110+
Started: true,
111+
})
112+
if err != nil {
113+
t.Fatal(err)
114+
}
115+
defer func() {
116+
if err := c.Terminate(ctx); err != nil {
117+
t.Logf("failed to terminate container: %s", err)
118+
}
119+
}()
120+
121+
host, err := c.Host(ctx)
122+
if err != nil {
123+
t.Fatal(err)
124+
}
125+
126+
port, err := c.MappedPort(ctx, "22/tcp")
127+
if err != nil {
128+
t.Fatal(err)
129+
}
130+
131+
if c.IsRunning() {
132+
connection := &connect.Connect{
133+
Alias: "test",
134+
Login: "root",
135+
Password: "password",
136+
Address: host,
137+
Type: connect.TypeSSH,
138+
CreatedAt: "",
139+
UpdatedAt: "",
140+
SshOptions: &connect.SshOptions{
141+
Port: port.Int(),
142+
PrivateKey: sshKeysName,
143+
},
144+
}
145+
146+
sshConnector := &connect.Ssh{}
147+
session, err := sshConnector.Session(connection)
148+
require.NoError(t, err)
149+
150+
defer func(session *ssh.Session) {
151+
require.NoError(t, session.Close())
152+
}(session)
153+
154+
require.NoError(t, session.Shell())
155+
}
156+
}

0 commit comments

Comments
 (0)