Something went wrong. Try again.
small gleam coding and (not yet) persistent agent daemon with a detachable cli forked from okami.mom/albedo
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194// --new-link relaunches a background server from web.json, so the argv it// builds must carry every option that started it: a tailnet-https server that// came back as --public-url would be rejected by cobra (the flags are// exclusive), a lost --local would share it with the tailnet, and a lost --allow// would close it to the devices it was opened to. The same file pins what a// second albedo web does against a recorded server: attach with the same// options, refuse different ones, and treat --allow as a set; and the links it// prints for a published origin. test/e2e/web_test.py covers one round trip;// these cover every combination of options without spawning a server each.package cli
import ( "bytes" "io" "net/http" "net/http/httptest" "os" "slices" "strings" "testing"
"albedo/cli/internal/webui"
"github.com/spf13/cobra")
func TestServeArgsCarryTheOptions(t *testing.T) { for _, test := range []struct { name string options webui.Options want []string }{ { name: "loopback", options: webui.Options{Port: 4317}, want: []string{"web", "--serve", "--no-open", "--port", "4317"}, }, { name: "this machine only", options: webui.Options{Port: 4317, Local: true}, want: []string{"web", "--serve", "--no-open", "--port", "4317", "--local"}, }, { name: "shared with networks", options: webui.Options{Port: 4317, Allow: []string{"10.0.0.0/8", "100.64.0.0/10"}}, want: []string{"web", "--serve", "--no-open", "--port", "4317", "--allow", "10.0.0.0/8", "--allow", "100.64.0.0/10"}, }, { name: "shared and published", options: webui.Options{Port: 4317, Allow: []string{"10.0.0.0/8"}, Public: "https://albedo.example"}, want: []string{"web", "--serve", "--no-open", "--port", "4317", "--allow", "10.0.0.0/8", "--public-url", "https://albedo.example"}, }, { name: "declared proxy", options: webui.Options{Port: 4317, Public: "https://albedo.example:443"}, want: []string{"web", "--serve", "--no-open", "--port", "4317", "--public-url", "https://albedo.example"}, }, { name: "tailnet https", options: webui.Options{Port: 4317, Public: "https://albedo.example.ts.net", TailnetHTTPS: true}, want: []string{"web", "--serve", "--no-open", "--port", "4317", "--tailnet-https"}, }, { name: "tailnet auth", options: webui.Options{Port: 4317, Public: "https://albedo.example.ts.net", TailnetHTTPS: true, TailnetAuth: true}, want: []string{"web", "--serve", "--no-open", "--port", "4317", "--tailnet-auth", "--tailnet-https"}, }, { name: "an origin that no longer parses", options: webui.Options{Port: 4317, Public: "ftp://albedo.example"}, want: []string{"web", "--serve", "--no-open", "--port", "4317"}, }, } { t.Run(test.name, func(t *testing.T) { if args := serveArgs(test.options); !slices.Equal(args, test.want) { t.Errorf("serveArgs(%+v) = %q, want %q", test.options, args, test.want) } }) }}
func TestBackgroundWebAttachesToTheRecordedOrigin(t *testing.T) { const public = "https://albedo.example.ts.net" recordedWeb(t, webui.Options{Port: 4317, Public: public}) var out bytes.Buffer streams := Streams{In: strings.NewReader(""), Out: &out, Err: io.Discard} if err := Execute(t.Context(), []string{"web", "--port", "4317"}, Dependencies{}, streams); err != nil { t.Fatal(err) } key, err := os.ReadFile(webui.KeyPath()) if err != nil { t.Fatal(err) } if want := public + "/?key=" + string(key); !strings.Contains(out.String(), want) { t.Errorf("printed %q, want %q", out.String(), want) }}
func TestBackgroundWebTreatsAllowedNetworksAsASet(t *testing.T) { recordedWeb(t, webui.Options{Port: 4317, Allow: []string{"10.0.0.0/8", "100.64.0.0/10"}}) streams := Streams{In: strings.NewReader(""), Out: io.Discard, Err: io.Discard} args := []string{ "web", "--allow", "100.64.0.0/10", "--allow", "10.0.0.0", "--allow", "100.64.0.0/10", } if err := Execute(t.Context(), args, Dependencies{}, streams); err != nil { t.Fatalf("the same networks in another order conflicted: %v", err) }}
func TestBackgroundWebRefusesDifferentOptions(t *testing.T) { recordedWeb(t, webui.Options{Port: 4317}) streams := Streams{In: strings.NewReader(""), Out: io.Discard, Err: io.Discard} err := Execute(t.Context(), []string{"web", "--port", "5000"}, Dependencies{}, streams) if err == nil || !strings.Contains(err.Error(), "different options") { t.Fatalf("a different port returned %v", err) }}
func TestBackgroundWebRefusesChangedTailnetAuth(t *testing.T) { recordedWeb(t, webui.Options{Port: 4317}) streams := Streams{In: strings.NewReader(""), Out: io.Discard, Err: io.Discard} err := Execute(t.Context(), []string{"web", "--tailnet-auth"}, Dependencies{}, streams) if err == nil || !strings.Contains(err.Error(), "different options") { t.Fatalf("enabling tailnet auth returned %v", err) }}
// recordedWeb writes a live-looking web.json and key, so the real web command// takes the attach path instead of spawning a child.func recordedWeb(t *testing.T, options webui.Options) { t.Helper() t.Setenv("ALBEDO_HOME", t.TempDir()) backend := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { w.WriteHeader(http.StatusOK) })) t.Cleanup(backend.Close) manifest := webui.Manifest{Options: options, PID: os.Getpid(), URL: backend.URL} if err := webui.WriteManifest(webui.ManifestPath(), manifest); err != nil { t.Fatal(err) } if err := os.WriteFile(webui.KeyPath(), []byte(strings.Repeat("ab", 24)), 0o600); err != nil { t.Fatal(err) }}
// TestPrintWebLinks pins the links a published server prints: a tailnet https// origin must not be followed by the direct http tailnet links, which lose the// secure context, while a proxy on another host keeps them.func TestPrintWebLinks(t *testing.T) { for _, test := range []struct { name, public string want, absent []string }{ { name: "tailnet https", public: "https://albedo.example.ts.net", want: []string{"serving at https://albedo.example.ts.net/?key=key", "on the network: http://10.0.0.5:4317/?key=key"}, absent: []string{"http://albedo.example.ts.net", "http://100.104.2.22"}, }, { name: "another proxy", public: "https://public.example", want: []string{"serving at https://public.example/?key=key", "on your tailnet: http://albedo.example.ts.net:4317/?key=key"}, }, } { t.Run(test.name, func(t *testing.T) { command := &cobra.Command{} var out bytes.Buffer command.SetOut(&out) manifest := webui.Manifest{ Options: webui.Options{Port: 4317, Public: test.public}, Names: []string{"albedo.example.ts.net", "albedo"}, Addresses: []string{"100.104.2.22", "10.0.0.5"}, } if err := printWebLinks(command, Dependencies{}, "key", manifest, true); err != nil { t.Fatal(err) } for _, want := range test.want { if !strings.Contains(out.String(), want) { t.Errorf("missing %q in %q", want, out.String()) } } for _, absent := range test.absent { if strings.Contains(out.String(), absent) { t.Errorf("printed %q in %q", absent, out.String()) } } }) }}