Skip to content

Commit

Permalink
wip api 2
Browse files Browse the repository at this point in the history
  • Loading branch information
heiytor committed Feb 8, 2024
1 parent a921c4d commit efddf0a
Show file tree
Hide file tree
Showing 6 changed files with 71 additions and 59 deletions.
2 changes: 2 additions & 0 deletions .env
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ SHELLHUB_VERSION=v0.14.2
# This specification details the network interface to which the gateway container will be bound.
SHELLHUB_BIND_ADDRESS=0.0.0.0

SHELLHUB_API_PORT=8080

# The HTTP listen port for the ShellHub web-based GUI, API and Reverse SSH tunnel.
# Values: any free port on host
SHELLHUB_HTTP_PORT=80
Expand Down
3 changes: 2 additions & 1 deletion api/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ var serverCmd = &cobra.Command{
// Provides the configuration for the API service.
// The values are load from the system environment variables.
type config struct {
HttpPort string `env:"HTTP_PORT"`
// MongoDB connection string (URI format)
MongoURI string `env:"MONGO_URI,default=mongodb://mongo:27017/main"`
// Redis connection string (URI format)
Expand Down Expand Up @@ -155,7 +156,7 @@ func startServer(cfg *config, store store.Store, cache storecache.Cache) error {
}
})

e.Logger.Fatal(e.Start(":8080"))
e.Logger.Fatal(e.Start(":" + cfg.HttpPort))

return nil
}
4 changes: 3 additions & 1 deletion docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ services:
image: shellhubio/api:${SHELLHUB_VERSION}
restart: unless-stopped
environment:
- HTTP_PORT=${SHELLHUB_API_PORT}
- SHELLHUB_VERSION=${SHELLHUB_VERSION}
- PRIVATE_KEY=/run/secrets/api_private_key
- PUBLIC_KEY=/run/secrets/api_public_key
Expand Down Expand Up @@ -57,7 +58,7 @@ services:
networks:
- shellhub
healthcheck:
test: "curl -f http://api:8080/api/healthcheck || exit 1"
test: "curl -f http://api:${SHELLHUB_API_PORT}/api/healthcheck || exit 1"
interval: 30s
start_period: 10s
ui:
Expand All @@ -81,6 +82,7 @@ services:
image: shellhubio/gateway:${SHELLHUB_VERSION}
restart: unless-stopped
environment:
- SHELLHUB_API_PORT=${SHELLHUB_API_PORT}
- SHELLHUB_DOMAIN=${SHELLHUB_DOMAIN}
- SHELLHUB_PUBLIC_URL_DOMAIN=${SHELLHUB_PUBLIC_URL_DOMAIN}
- SHELLHUB_VERSION=${SHELLHUB_VERSION}
Expand Down
23 changes: 14 additions & 9 deletions gateway/conf.d/shellhub.conf
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,11 @@ server {
server_name {{ (env.Getenv "SHELLHUB_DOMAIN") }};
resolver 127.0.0.11 ipv6=off;

set $api_port {{ env.Getenv "SHELLHUB_API_PORT" }};
set $api_endpoint "api:${api_port}";

# set $api_endpoint "api:${(env.Getenv 'SHELLHUB_API_PORT')}";

# Load configuration files for the default server block
include /etc/nginx/default.d/*.conf;

Expand Down Expand Up @@ -53,7 +58,7 @@ server {
}

location /api {
set $upstream api:8080;
set $upstream $api_endpoint;

auth_request /auth;
auth_request_set $tenant_id $upstream_http_x_tenant_id;
Expand All @@ -75,7 +80,7 @@ server {
}

location ~ ^/(install.sh|kickstart.sh)$ {
set $upstream api:8080;
set $upstream $api_endpoint;
rewrite ^/(.*)$ /api/install break;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Proto $x_forwarded_proto;
Expand All @@ -84,7 +89,7 @@ server {
}

location /api/auth/user {
set $upstream api:8080;
set $upstream $api_endpoint;

auth_request /auth/skip;
auth_request_set $tenant_id $upstream_http_x_tenant_id;
Expand Down Expand Up @@ -188,7 +193,7 @@ server {
}

location /ssh/auth {
set $upstream api:8080;
set $upstream $api_endpoint;
auth_request /auth;
auth_request_set $device_uid $upstream_http_x_device_uid;
error_page 500 =401 /auth;
Expand Down Expand Up @@ -357,7 +362,7 @@ server {
}

location /api/devices/auth {
set $upstream api:8080;
set $upstream $api_endpoint;
auth_request off;
rewrite ^/api/(.*)$ /api/$1 break;
{{ if bool (env.Getenv "SHELLHUB_PROXY") -}}
Expand All @@ -369,7 +374,7 @@ server {
}

location /api/login {
set $upstream api:8080;
set $upstream $api_endpoint;
auth_request off;
rewrite ^/api/(.*)$ /api/$1 break;
proxy_pass http://$upstream;
Expand All @@ -383,14 +388,14 @@ server {
}

location /auth {
set $upstream_auth api:8080;
set $upstream_auth $api_endpoint;
internal;
rewrite ^/(.*)$ /internal/$1 break;
proxy_pass http://$upstream_auth;
}

location /auth/skip {
set $upstream_auth api:8080;
set $upstream_auth $api_endpoint;
internal;
rewrite ^/auth/(.*)$ /internal/auth?args=$1 break;
proxy_pass http://$upstream_auth;
Expand All @@ -414,7 +419,7 @@ server {
}

location /info {
set $upstream api:8080;
set $upstream $api_endpoint;

proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Port $x_forwarded_port;
Expand Down
64 changes: 28 additions & 36 deletions tests/api_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,20 @@ package main
import (
"encoding/json"
"fmt"
"io"
"net/http"
"strconv"
"testing"

"github.com/go-resty/resty/v2"
"github.com/stretchr/testify/assert"
)

func TestInfo(t *testing.T) {
t.Parallel()

type Expected struct {
res map[string]interface{}
err error
body map[string]interface{}
status int
err error
}

cases := []struct {
Expand All @@ -25,40 +27,44 @@ func TestInfo(t *testing.T) {
{
description: "case 1",
compose: New().
WithEnv("SHELLHUB_API_PORT", strconv.Itoa(getFreePort(t))).
WithEnv("SHELLHUB_HTTP_PORT", strconv.Itoa(getFreePort(t))).
WithEnv("SHELLHUB_SSH_PORT", strconv.Itoa(getFreePort(t))).
WithEnv("SHELLHUB_VERSION", "v0.14.2").
WithEnv("SHELLHUB_VERSION", "v0.25.2").
Build(),
expected: func(httpPort, sshPort string) Expected {
return Expected{
res: map[string]interface{}{
body: map[string]interface{}{
"endpoints": map[string]interface{}{
"api": fmt.Sprintf("localhost:%s", httpPort),
"ssh": fmt.Sprintf("localhost:%s", sshPort),
},
"version": "v0.14.2",
"version": "v0.25.2",
},
err: nil,
status: 200,
err: nil,
}
},
},
{
description: "case 2",
compose: New().
WithEnv("SHELLHUB_API_PORT", strconv.Itoa(getFreePort(t))).
WithEnv("SHELLHUB_HTTP_PORT", strconv.Itoa(getFreePort(t))).
WithEnv("SHELLHUB_SSH_PORT", strconv.Itoa(getFreePort(t))).
WithEnv("SHELLHUB_VERSION", "v0.10.2").
Build(),
expected: func(httpPort, sshPort string) Expected {
return Expected{
res: map[string]interface{}{
body: map[string]interface{}{
"endpoints": map[string]interface{}{
"api": fmt.Sprintf("localhost:%s", httpPort),
"ssh": fmt.Sprintf("localhost:%s", sshPort),
},
"version": "v0.10.2",
},
err: nil,
status: 200,
err: nil,
}
},
},
Expand All @@ -68,36 +74,22 @@ func TestInfo(t *testing.T) {
// Avoid "loop variable <> captured by func literal"
tc := tt

t.Run(tc.description, func(t *testing.T) {
tc.compose.Run(t, tc.description, func(t *testing.T) {
t.Parallel()

tc.compose.Run(t, func() {
fmt.Printf("desciption %s\n", tc.description)

fmt.Printf("%s request to %s\n", tc.description, fmt.Sprintf("http://localhost:%s/info", tc.compose.GetEnv("SHELLHUB_HTTP_PORT")))

// res, _ := resty.
// New().
// R().
// Get(fmt.Sprintf("http://localhost:%s/info", tc.compose.GetEnv("SHELLHUB_HTTP_PORT")))

res, err := http.Get(fmt.Sprintf("http://localhost:%s/info", tc.compose.GetEnv("SHELLHUB_HTTP_PORT")))
assert.NoError(t, err)
defer res.Body.Close()

foo, err := io.ReadAll(res.Body)
assert.NoError(t, err)
res, err := resty.
New().
R().
Get(fmt.Sprintf("http://localhost:%s/info", tc.compose.GetEnv("SHELLHUB_HTTP_PORT")))

body := map[string]interface{}{}
assert.NoError(t, json.Unmarshal(foo, &body))
body := map[string]interface{}{}
assert.NoError(t, json.Unmarshal(res.Body(), &body))

fmt.Printf("%s http: %+v\n", tc.description, body)
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"))
fmt.Printf("%s expected: %+v\n", tc.description, tc.expected(tc.compose.GetEnv("SHELLHUB_HTTP_PORT"), tc.compose.GetEnv("SHELLHUB_SSH_PORT")).res)
fmt.Println("********************************************")
//
// assert.Equal(t, tc.expected(tc.compose.GetEnv("SHELLHUB_HTTP_PORT"), tc.compose.GetEnv("SHELLHUB_SSH_PORT")), Expected{body, err})
})
assert.Equal(
t,
tc.expected(tc.compose.GetEnv("SHELLHUB_HTTP_PORT"), tc.compose.GetEnv("SHELLHUB_SSH_PORT")),
Expected{body, res.StatusCode(), err},
)
})
}
}
34 changes: 22 additions & 12 deletions tests/enviroment.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,12 @@ package main
import (
"context"
"testing"
"time"

"github.com/joho/godotenv"
"github.com/stretchr/testify/assert"
testcontainers "github.com/testcontainers/testcontainers-go/modules/compose"
"github.com/testcontainers/testcontainers-go/wait"
)

type Enviroment struct {
Expand Down Expand Up @@ -46,20 +48,28 @@ func (e *Enviroment) GetEnv(key string) string {
return e.env[key]
}

func (e *Enviroment) Run(t *testing.T, cb func()) {
compose, err := testcontainers.NewDockerCompose("../docker-compose.yml", "../docker-compose.dev.yml")
assert.NoError(t, err)

t.Cleanup(func() {
err := compose.Down(context.Background(), testcontainers.RemoveOrphans(true), testcontainers.RemoveImagesLocal)
func (e *Enviroment) Run(t *testing.T, description string, cb func(t *testing.T)) {
t.Run(description, func(t *testing.T) {
compose, err := testcontainers.NewDockerCompose("../docker-compose.yml", "../docker-compose.dev.yml")
assert.NoError(t, err)
})

ctx, cancel := context.WithCancel(context.Background())
t.Cleanup(cancel)
t.Cleanup(func() {
err := compose.Down(context.Background(), testcontainers.RemoveOrphans(true), testcontainers.RemoveImagesLocal)
assert.NoError(t, err)
})

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

cb()
assert.NoError(
t,
compose.
WithEnv(e.env).
// TODO: how can we wait for "api"?
WaitForService("gateway", wait.ForHTTP("/healthcheck").WithStartupTimeout(30*time.Second)).
Up(ctx, testcontainers.Wait(true)),
)

cb(t)
})
}

0 comments on commit efddf0a

Please sign in to comment.