Skip to content

Commit f793f06

Browse files
committed
Add support for container API call from http plugin
1 parent 29b5c97 commit f793f06

File tree

9 files changed

+106
-40
lines changed

9 files changed

+106
-40
lines changed

internal/app/action/action.go

Lines changed: 34 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -36,27 +36,28 @@ var embedFS = hashfs.NewFS(embedHtml)
3636
// and an API interface
3737
type Action struct {
3838
*types.Logger
39-
isDev bool
40-
name string
41-
description string
42-
appPath string
43-
run starlark.Callable
44-
suggest starlark.Callable
45-
params []apptype.AppParam
46-
paramValuesStr map[string]string
47-
paramDict starlark.StringDict
48-
actionTemplate *template.Template
49-
pagePath string
50-
AppTemplate *template.Template
51-
StyleType types.StyleType
52-
LightTheme string
53-
DarkTheme string
39+
isDev bool
40+
name string
41+
description string
42+
appPath string
43+
run starlark.Callable
44+
suggest starlark.Callable
45+
params []apptype.AppParam
46+
paramValuesStr map[string]string
47+
paramDict starlark.StringDict
48+
actionTemplate *template.Template
49+
pagePath string
50+
AppTemplate *template.Template
51+
StyleType types.StyleType
52+
LightTheme string
53+
DarkTheme string
54+
containerProxyUrl string
5455
}
5556

5657
// NewAction creates a new action
5758
func NewAction(logger *types.Logger, sourceFS *appfs.SourceFs, isDev bool, name, description, apath string, run, suggest starlark.Callable,
5859
params []apptype.AppParam, paramValuesStr map[string]string, paramDict starlark.StringDict,
59-
appPath string, styleType types.StyleType) (*Action, error) {
60+
appPath string, styleType types.StyleType, containerProxyUrl string) (*Action, error) {
6061

6162
funcMap := system.GetFuncMap()
6263

@@ -96,19 +97,20 @@ func NewAction(logger *types.Logger, sourceFS *appfs.SourceFs, isDev bool, name,
9697
}
9798

9899
return &Action{
99-
Logger: &appLogger,
100-
isDev: isDev,
101-
name: name,
102-
description: description,
103-
appPath: appPath,
104-
pagePath: pagePath,
105-
run: run,
106-
suggest: suggest,
107-
params: params,
108-
paramValuesStr: paramValuesStr,
109-
paramDict: paramDict,
110-
actionTemplate: tmpl,
111-
StyleType: styleType,
100+
Logger: &appLogger,
101+
isDev: isDev,
102+
name: name,
103+
description: description,
104+
appPath: appPath,
105+
pagePath: pagePath,
106+
run: run,
107+
suggest: suggest,
108+
params: params,
109+
paramValuesStr: paramValuesStr,
110+
paramDict: paramDict,
111+
actionTemplate: tmpl,
112+
StyleType: styleType,
113+
containerProxyUrl: containerProxyUrl,
112114
// AppTemplate and Theme names are initialized later
113115
}, nil
114116
}
@@ -149,6 +151,9 @@ func (a *Action) runAction(w http.ResponseWriter, r *http.Request) {
149151

150152
// Save the request context in the starlark thread local
151153
thread.SetLocal(types.TL_CONTEXT, r.Context())
154+
if a.containerProxyUrl != "" {
155+
thread.SetLocal(types.TL_CONTAINER_URL, a.containerProxyUrl)
156+
}
152157
isHtmxRequest := r.Header.Get("HX-Request") == "true"
153158

154159
r.ParseForm()

internal/app/apptype/builtins.go

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -405,16 +405,17 @@ func CreateBuiltin() starlark.StringDict {
405405
ACTION: starlark.NewBuiltin(ACTION, createActionBuiltin),
406406
RESULT: starlark.NewBuiltin(RESULT, createResultBuiltin),
407407

408-
GET: starlark.String(GET),
409-
POST: starlark.String(POST),
410-
PUT: starlark.String(PUT),
411-
DELETE: starlark.String(DELETE),
412-
JSON: starlark.String(JSON),
413-
TEXT: starlark.String(TEXT),
414-
READ: starlark.String(READ),
415-
WRITE: starlark.String(WRITE),
416-
AUTO: starlark.String(AUTO),
417-
TABLE: starlark.String(TABLE),
408+
GET: starlark.String(GET),
409+
POST: starlark.String(POST),
410+
PUT: starlark.String(PUT),
411+
DELETE: starlark.String(DELETE),
412+
JSON: starlark.String(JSON),
413+
TEXT: starlark.String(TEXT),
414+
READ: starlark.String(READ),
415+
WRITE: starlark.String(WRITE),
416+
AUTO: starlark.String(AUTO),
417+
TABLE: starlark.String(TABLE),
418+
"CONTAINER_URL": starlark.String(CONTAINER_URL),
418419
},
419420
},
420421
}

internal/app/handler.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,9 @@ func (a *App) createHandlerFunc(fullHtml, fragment string, handler starlark.Call
5858

5959
// Save the request context in the starlark thread local
6060
thread.SetLocal(types.TL_CONTEXT, r.Context())
61+
if a.containerManager != nil {
62+
thread.SetLocal(types.TL_CONTAINER_URL, a.containerManager.GetProxyUrl())
63+
}
6164

6265
isHtmxRequest := r.Header.Get("HX-Request") == "true" && !(r.Header.Get("HX-Boosted") == "true")
6366

internal/app/setup.go

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -487,8 +487,13 @@ func (a *App) addAction(count int, val starlark.Value, router *chi.Mux) error {
487487
if !strings.HasPrefix(path, "/") {
488488
path = "/" + path
489489
}
490+
containerProxyUrl := ""
491+
if a.containerManager != nil {
492+
containerProxyUrl = a.containerManager.GetProxyUrl()
493+
}
490494
action, err := action.NewAction(a.Logger, a.sourceFS, a.IsDev, name, description, path, run, suggest,
491-
slices.Collect(maps.Values(a.paramInfo)), a.paramValuesStr, a.paramDict, a.Path, a.appStyle.GetStyleType())
495+
slices.Collect(maps.Values(a.paramInfo)), a.paramValuesStr, a.paramDict, a.Path, a.appStyle.GetStyleType(),
496+
containerProxyUrl)
492497
if err != nil {
493498
return fmt.Errorf("error creating action %s: %w", name, err)
494499
}

internal/types/types.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ const (
3232
TL_DEFER_MAP = "TL_defer_map"
3333
TL_CURRENT_MODULE_FULL_PATH = "TL_current_module_full_path"
3434
TL_PLUGIN_API_FAILED_ERROR = "TL_plugin_api_failed_error"
35+
TL_CONTAINER_URL = "TL_container_url"
3536
)
3637

3738
const (

plugins/http.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import (
1717
"strings"
1818

1919
"github.com/claceio/clace/internal/app"
20+
"github.com/claceio/clace/internal/app/apptype"
2021
"github.com/claceio/clace/internal/app/starlark_type"
2122
"github.com/claceio/clace/internal/plugin"
2223
"github.com/claceio/clace/internal/types"
@@ -117,6 +118,17 @@ func (h *httpPlugin) reqMethod(method string) func(thread *starlark.Thread, _ *s
117118
return nil, err
118119
}
119120

121+
if strings.HasPrefix(rawurl, apptype.CONTAINER_URL) {
122+
// If the url starts with the container url, we need to replace it with the container proxy url
123+
rawurl = strings.TrimPrefix(rawurl, apptype.CONTAINER_URL)
124+
containerProxyUrl := thread.Local(types.TL_CONTAINER_URL)
125+
containerProxyUrlStr, ok := containerProxyUrl.(string)
126+
if !ok || containerProxyUrlStr == "" {
127+
return nil, fmt.Errorf("container proxy url not set")
128+
}
129+
rawurl = containerProxyUrlStr + rawurl
130+
}
131+
120132
if err = setQueryParams(&rawurl, params); err != nil {
121133
return nil, err
122134
}

tests/flaskhttp/app.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
from flask import Flask
2+
3+
app = Flask(__name__)
4+
5+
@app.route("/")
6+
def root():
7+
return "hello"
8+
9+
@app.route("/test")
10+
def hello_world():
11+
return "testworld"

tests/flaskhttp/app.star

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
load("container.in", "container")
2+
load("http.in", "http")
3+
4+
def handler(req):
5+
v1 = http.get(ace.CONTAINER_URL).value.body()
6+
v2 = http.get(ace.CONTAINER_URL + "/test").value.body()
7+
return {"v1": v1, "v2": v2}
8+
9+
app = ace.app("Flask Http Test",
10+
routes=[
11+
ace.api("/")
12+
],
13+
container=container.config(container.AUTO, port=param.port),
14+
permissions=[
15+
ace.permission("container.in", "config", [container.AUTO]),
16+
ace.permission("http.in", "get")
17+
]
18+
)

tests/test_containers.yaml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,3 +75,13 @@ tests:
7575
command: ../clace app create --spec image --approve --param image=nginx - /cont_image_error
7676
stderr: param port is a required param, a value has to be provided
7777
exit-code: 1
78+
79+
# Test http plugin call without proxy
80+
container0500: # setup app
81+
command: ../clace app create --spec python-flask --approve ./flaskhttp /cont_fh
82+
container0510: # check curl
83+
command: curl -sS localhost:${HTTP_PORT}/cont_fh
84+
stdout: '"v1":"hello"'
85+
container0520: # check curl
86+
command: curl -sS localhost:${HTTP_PORT}/cont_fh
87+
stdout: '"v2":"testworld"'

0 commit comments

Comments
 (0)