Skip to content

Commit efddf0a

Browse files
committed
wip api 2
1 parent a921c4d commit efddf0a

File tree

6 files changed

+71
-59
lines changed

6 files changed

+71
-59
lines changed

.env

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ SHELLHUB_VERSION=v0.14.2
77
# This specification details the network interface to which the gateway container will be bound.
88
SHELLHUB_BIND_ADDRESS=0.0.0.0
99

10+
SHELLHUB_API_PORT=8080
11+
1012
# The HTTP listen port for the ShellHub web-based GUI, API and Reverse SSH tunnel.
1113
# Values: any free port on host
1214
SHELLHUB_HTTP_PORT=80

api/server.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ var serverCmd = &cobra.Command{
6363
// Provides the configuration for the API service.
6464
// The values are load from the system environment variables.
6565
type config struct {
66+
HttpPort string `env:"HTTP_PORT"`
6667
// MongoDB connection string (URI format)
6768
MongoURI string `env:"MONGO_URI,default=mongodb://mongo:27017/main"`
6869
// Redis connection string (URI format)
@@ -155,7 +156,7 @@ func startServer(cfg *config, store store.Store, cache storecache.Cache) error {
155156
}
156157
})
157158

158-
e.Logger.Fatal(e.Start(":8080"))
159+
e.Logger.Fatal(e.Start(":" + cfg.HttpPort))
159160

160161
return nil
161162
}

docker-compose.yml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ services:
2727
image: shellhubio/api:${SHELLHUB_VERSION}
2828
restart: unless-stopped
2929
environment:
30+
- HTTP_PORT=${SHELLHUB_API_PORT}
3031
- SHELLHUB_VERSION=${SHELLHUB_VERSION}
3132
- PRIVATE_KEY=/run/secrets/api_private_key
3233
- PUBLIC_KEY=/run/secrets/api_public_key
@@ -57,7 +58,7 @@ services:
5758
networks:
5859
- shellhub
5960
healthcheck:
60-
test: "curl -f http://api:8080/api/healthcheck || exit 1"
61+
test: "curl -f http://api:${SHELLHUB_API_PORT}/api/healthcheck || exit 1"
6162
interval: 30s
6263
start_period: 10s
6364
ui:
@@ -81,6 +82,7 @@ services:
8182
image: shellhubio/gateway:${SHELLHUB_VERSION}
8283
restart: unless-stopped
8384
environment:
85+
- SHELLHUB_API_PORT=${SHELLHUB_API_PORT}
8486
- SHELLHUB_DOMAIN=${SHELLHUB_DOMAIN}
8587
- SHELLHUB_PUBLIC_URL_DOMAIN=${SHELLHUB_PUBLIC_URL_DOMAIN}
8688
- SHELLHUB_VERSION=${SHELLHUB_VERSION}

gateway/conf.d/shellhub.conf

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,11 @@ server {
2424
server_name {{ (env.Getenv "SHELLHUB_DOMAIN") }};
2525
resolver 127.0.0.11 ipv6=off;
2626

27+
set $api_port {{ env.Getenv "SHELLHUB_API_PORT" }};
28+
set $api_endpoint "api:${api_port}";
29+
30+
# set $api_endpoint "api:${(env.Getenv 'SHELLHUB_API_PORT')}";
31+
2732
# Load configuration files for the default server block
2833
include /etc/nginx/default.d/*.conf;
2934

@@ -53,7 +58,7 @@ server {
5358
}
5459

5560
location /api {
56-
set $upstream api:8080;
61+
set $upstream $api_endpoint;
5762

5863
auth_request /auth;
5964
auth_request_set $tenant_id $upstream_http_x_tenant_id;
@@ -75,7 +80,7 @@ server {
7580
}
7681

7782
location ~ ^/(install.sh|kickstart.sh)$ {
78-
set $upstream api:8080;
83+
set $upstream $api_endpoint;
7984
rewrite ^/(.*)$ /api/install break;
8085
proxy_set_header X-Forwarded-Host $host;
8186
proxy_set_header X-Forwarded-Proto $x_forwarded_proto;
@@ -84,7 +89,7 @@ server {
8489
}
8590

8691
location /api/auth/user {
87-
set $upstream api:8080;
92+
set $upstream $api_endpoint;
8893

8994
auth_request /auth/skip;
9095
auth_request_set $tenant_id $upstream_http_x_tenant_id;
@@ -188,7 +193,7 @@ server {
188193
}
189194

190195
location /ssh/auth {
191-
set $upstream api:8080;
196+
set $upstream $api_endpoint;
192197
auth_request /auth;
193198
auth_request_set $device_uid $upstream_http_x_device_uid;
194199
error_page 500 =401 /auth;
@@ -357,7 +362,7 @@ server {
357362
}
358363

359364
location /api/devices/auth {
360-
set $upstream api:8080;
365+
set $upstream $api_endpoint;
361366
auth_request off;
362367
rewrite ^/api/(.*)$ /api/$1 break;
363368
{{ if bool (env.Getenv "SHELLHUB_PROXY") -}}
@@ -369,7 +374,7 @@ server {
369374
}
370375

371376
location /api/login {
372-
set $upstream api:8080;
377+
set $upstream $api_endpoint;
373378
auth_request off;
374379
rewrite ^/api/(.*)$ /api/$1 break;
375380
proxy_pass http://$upstream;
@@ -383,14 +388,14 @@ server {
383388
}
384389

385390
location /auth {
386-
set $upstream_auth api:8080;
391+
set $upstream_auth $api_endpoint;
387392
internal;
388393
rewrite ^/(.*)$ /internal/$1 break;
389394
proxy_pass http://$upstream_auth;
390395
}
391396

392397
location /auth/skip {
393-
set $upstream_auth api:8080;
398+
set $upstream_auth $api_endpoint;
394399
internal;
395400
rewrite ^/auth/(.*)$ /internal/auth?args=$1 break;
396401
proxy_pass http://$upstream_auth;
@@ -414,7 +419,7 @@ server {
414419
}
415420

416421
location /info {
417-
set $upstream api:8080;
422+
set $upstream $api_endpoint;
418423

419424
proxy_set_header X-Forwarded-Host $host;
420425
proxy_set_header X-Forwarded-Port $x_forwarded_port;

tests/api_test.go

Lines changed: 28 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -3,18 +3,20 @@ package main
33
import (
44
"encoding/json"
55
"fmt"
6-
"io"
7-
"net/http"
86
"strconv"
97
"testing"
108

9+
"github.com/go-resty/resty/v2"
1110
"github.com/stretchr/testify/assert"
1211
)
1312

1413
func TestInfo(t *testing.T) {
14+
t.Parallel()
15+
1516
type Expected struct {
16-
res map[string]interface{}
17-
err error
17+
body map[string]interface{}
18+
status int
19+
err error
1820
}
1921

2022
cases := []struct {
@@ -25,40 +27,44 @@ func TestInfo(t *testing.T) {
2527
{
2628
description: "case 1",
2729
compose: New().
30+
WithEnv("SHELLHUB_API_PORT", strconv.Itoa(getFreePort(t))).
2831
WithEnv("SHELLHUB_HTTP_PORT", strconv.Itoa(getFreePort(t))).
2932
WithEnv("SHELLHUB_SSH_PORT", strconv.Itoa(getFreePort(t))).
30-
WithEnv("SHELLHUB_VERSION", "v0.14.2").
33+
WithEnv("SHELLHUB_VERSION", "v0.25.2").
3134
Build(),
3235
expected: func(httpPort, sshPort string) Expected {
3336
return Expected{
34-
res: map[string]interface{}{
37+
body: map[string]interface{}{
3538
"endpoints": map[string]interface{}{
3639
"api": fmt.Sprintf("localhost:%s", httpPort),
3740
"ssh": fmt.Sprintf("localhost:%s", sshPort),
3841
},
39-
"version": "v0.14.2",
42+
"version": "v0.25.2",
4043
},
41-
err: nil,
44+
status: 200,
45+
err: nil,
4246
}
4347
},
4448
},
4549
{
4650
description: "case 2",
4751
compose: New().
52+
WithEnv("SHELLHUB_API_PORT", strconv.Itoa(getFreePort(t))).
4853
WithEnv("SHELLHUB_HTTP_PORT", strconv.Itoa(getFreePort(t))).
4954
WithEnv("SHELLHUB_SSH_PORT", strconv.Itoa(getFreePort(t))).
5055
WithEnv("SHELLHUB_VERSION", "v0.10.2").
5156
Build(),
5257
expected: func(httpPort, sshPort string) Expected {
5358
return Expected{
54-
res: map[string]interface{}{
59+
body: map[string]interface{}{
5560
"endpoints": map[string]interface{}{
5661
"api": fmt.Sprintf("localhost:%s", httpPort),
5762
"ssh": fmt.Sprintf("localhost:%s", sshPort),
5863
},
5964
"version": "v0.10.2",
6065
},
61-
err: nil,
66+
status: 200,
67+
err: nil,
6268
}
6369
},
6470
},
@@ -68,36 +74,22 @@ func TestInfo(t *testing.T) {
6874
// Avoid "loop variable <> captured by func literal"
6975
tc := tt
7076

71-
t.Run(tc.description, func(t *testing.T) {
77+
tc.compose.Run(t, tc.description, func(t *testing.T) {
7278
t.Parallel()
7379

74-
tc.compose.Run(t, func() {
75-
fmt.Printf("desciption %s\n", tc.description)
76-
77-
fmt.Printf("%s request to %s\n", tc.description, fmt.Sprintf("http://localhost:%s/info", tc.compose.GetEnv("SHELLHUB_HTTP_PORT")))
78-
79-
// res, _ := resty.
80-
// New().
81-
// R().
82-
// Get(fmt.Sprintf("http://localhost:%s/info", tc.compose.GetEnv("SHELLHUB_HTTP_PORT")))
83-
84-
res, err := http.Get(fmt.Sprintf("http://localhost:%s/info", tc.compose.GetEnv("SHELLHUB_HTTP_PORT")))
85-
assert.NoError(t, err)
86-
defer res.Body.Close()
87-
88-
foo, err := io.ReadAll(res.Body)
89-
assert.NoError(t, err)
80+
res, err := resty.
81+
New().
82+
R().
83+
Get(fmt.Sprintf("http://localhost:%s/info", tc.compose.GetEnv("SHELLHUB_HTTP_PORT")))
9084

91-
body := map[string]interface{}{}
92-
assert.NoError(t, json.Unmarshal(foo, &body))
85+
body := map[string]interface{}{}
86+
assert.NoError(t, json.Unmarshal(res.Body(), &body))
9387

94-
fmt.Printf("%s http: %+v\n", tc.description, body)
95-
fmt.Printf("%s env: %s %s %s\n", tc.description, tc.compose.GetEnv("SHELLHUB_HTTP_PORT"), tc.compose.GetEnv("SHELLHUB_SSH_PORT"), tc.compose.GetEnv("SHELLHUB_VERSION"))
96-
fmt.Printf("%s expected: %+v\n", tc.description, tc.expected(tc.compose.GetEnv("SHELLHUB_HTTP_PORT"), tc.compose.GetEnv("SHELLHUB_SSH_PORT")).res)
97-
fmt.Println("********************************************")
98-
//
99-
// assert.Equal(t, tc.expected(tc.compose.GetEnv("SHELLHUB_HTTP_PORT"), tc.compose.GetEnv("SHELLHUB_SSH_PORT")), Expected{body, err})
100-
})
88+
assert.Equal(
89+
t,
90+
tc.expected(tc.compose.GetEnv("SHELLHUB_HTTP_PORT"), tc.compose.GetEnv("SHELLHUB_SSH_PORT")),
91+
Expected{body, res.StatusCode(), err},
92+
)
10193
})
10294
}
10395
}

tests/enviroment.go

Lines changed: 22 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,12 @@ package main
33
import (
44
"context"
55
"testing"
6+
"time"
67

78
"github.com/joho/godotenv"
89
"github.com/stretchr/testify/assert"
910
testcontainers "github.com/testcontainers/testcontainers-go/modules/compose"
11+
"github.com/testcontainers/testcontainers-go/wait"
1012
)
1113

1214
type Enviroment struct {
@@ -46,20 +48,28 @@ func (e *Enviroment) GetEnv(key string) string {
4648
return e.env[key]
4749
}
4850

49-
func (e *Enviroment) Run(t *testing.T, cb func()) {
50-
compose, err := testcontainers.NewDockerCompose("../docker-compose.yml", "../docker-compose.dev.yml")
51-
assert.NoError(t, err)
52-
53-
t.Cleanup(func() {
54-
err := compose.Down(context.Background(), testcontainers.RemoveOrphans(true), testcontainers.RemoveImagesLocal)
51+
func (e *Enviroment) Run(t *testing.T, description string, cb func(t *testing.T)) {
52+
t.Run(description, func(t *testing.T) {
53+
compose, err := testcontainers.NewDockerCompose("../docker-compose.yml", "../docker-compose.dev.yml")
5554
assert.NoError(t, err)
56-
})
5755

58-
ctx, cancel := context.WithCancel(context.Background())
59-
t.Cleanup(cancel)
56+
t.Cleanup(func() {
57+
err := compose.Down(context.Background(), testcontainers.RemoveOrphans(true), testcontainers.RemoveImagesLocal)
58+
assert.NoError(t, err)
59+
})
6060

61-
err = compose.WithEnv(e.env).Up(ctx, testcontainers.Wait(true))
62-
assert.NoError(t, err)
61+
ctx, cancel := context.WithCancel(context.Background())
62+
t.Cleanup(cancel)
6363

64-
cb()
64+
assert.NoError(
65+
t,
66+
compose.
67+
WithEnv(e.env).
68+
// TODO: how can we wait for "api"?
69+
WaitForService("gateway", wait.ForHTTP("/healthcheck").WithStartupTimeout(30*time.Second)).
70+
Up(ctx, testcontainers.Wait(true)),
71+
)
72+
73+
cb(t)
74+
})
6575
}

0 commit comments

Comments
 (0)