Skip to content

Commit b246f08

Browse files
authored
chore: move app URL parsing to its own package (#11651)
* chore: move app url parsing to it's own package
1 parent 1aee8da commit b246f08

File tree

32 files changed

+165
-133
lines changed

32 files changed

+165
-133
lines changed

cli/clibase/values.go

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,28 @@ func (i *Validator[T]) Type() string {
5959
return i.Value.Type()
6060
}
6161

62+
func (i *Validator[T]) MarshalYAML() (interface{}, error) {
63+
m, ok := any(i.Value).(yaml.Marshaler)
64+
if !ok {
65+
return i.Value, nil
66+
}
67+
return m.MarshalYAML()
68+
}
69+
70+
func (i *Validator[T]) UnmarshalYAML(n *yaml.Node) error {
71+
return n.Decode(i.Value)
72+
}
73+
74+
func (i *Validator[T]) MarshalJSON() ([]byte, error) {
75+
return json.Marshal(i.Value)
76+
}
77+
78+
func (i *Validator[T]) UnmarshalJSON(b []byte) error {
79+
return json.Unmarshal(b, i.Value)
80+
}
81+
82+
func (i *Validator[T]) Underlying() pflag.Value { return i.Value }
83+
6284
// values.go contains a standard set of value types that can be used as
6385
// Option Values.
6486

@@ -378,6 +400,7 @@ func (s *Struct[T]) String() string {
378400
return string(byt)
379401
}
380402

403+
// nolint:revive
381404
func (s *Struct[T]) MarshalYAML() (interface{}, error) {
382405
var n yaml.Node
383406
err := n.Encode(s.Value)
@@ -387,6 +410,7 @@ func (s *Struct[T]) MarshalYAML() (interface{}, error) {
387410
return n, nil
388411
}
389412

413+
// nolint:revive
390414
func (s *Struct[T]) UnmarshalYAML(n *yaml.Node) error {
391415
// HACK: for compatibility with flags, we use nil slices instead of empty
392416
// slices. In most cases, nil slices and empty slices are treated
@@ -403,10 +427,12 @@ func (s *Struct[T]) Type() string {
403427
return fmt.Sprintf("struct[%T]", s.Value)
404428
}
405429

430+
// nolint:revive
406431
func (s *Struct[T]) MarshalJSON() ([]byte, error) {
407432
return json.Marshal(s.Value)
408433
}
409434

435+
// nolint:revive
410436
func (s *Struct[T]) UnmarshalJSON(b []byte) error {
411437
return json.Unmarshal(b, &s.Value)
412438
}

cli/clibase/yaml.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import (
66
"strings"
77

88
"github.com/mitchellh/go-wordwrap"
9+
"github.com/spf13/pflag"
910
"golang.org/x/xerrors"
1011
"gopkg.in/yaml.v3"
1112
)
@@ -74,13 +75,16 @@ func (optSet *OptionSet) MarshalYAML() (any, error) {
7475
Value: opt.YAML,
7576
HeadComment: comment,
7677
}
78+
79+
_, isValidator := opt.Value.(interface{ Underlying() pflag.Value })
7780
var valueNode yaml.Node
7881
if opt.Value == nil {
7982
valueNode = yaml.Node{
8083
Kind: yaml.ScalarNode,
8184
Value: "null",
8285
}
83-
} else if m, ok := opt.Value.(yaml.Marshaler); ok {
86+
} else if m, ok := opt.Value.(yaml.Marshaler); ok && !isValidator {
87+
// Validators do a wrap, and should be handled by the else statement.
8488
v, err := m.MarshalYAML()
8589
if err != nil {
8690
return nil, xerrors.Errorf(

cli/server.go

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -53,8 +53,6 @@ import (
5353
"gopkg.in/yaml.v3"
5454
"tailscale.com/tailcfg"
5555

56-
"github.com/coder/pretty"
57-
5856
"cdr.dev/slog"
5957
"cdr.dev/slog/sloggers/sloghuman"
6058
"github.com/coder/coder/v2/buildinfo"
@@ -75,7 +73,6 @@ import (
7573
"github.com/coder/coder/v2/coderd/devtunnel"
7674
"github.com/coder/coder/v2/coderd/externalauth"
7775
"github.com/coder/coder/v2/coderd/gitsshkey"
78-
"github.com/coder/coder/v2/coderd/httpapi"
7976
"github.com/coder/coder/v2/coderd/httpmw"
8077
"github.com/coder/coder/v2/coderd/oauthpki"
8178
"github.com/coder/coder/v2/coderd/prometheusmetrics"
@@ -89,6 +86,7 @@ import (
8986
"github.com/coder/coder/v2/coderd/util/slice"
9087
stringutil "github.com/coder/coder/v2/coderd/util/strings"
9188
"github.com/coder/coder/v2/coderd/workspaceapps"
89+
"github.com/coder/coder/v2/coderd/workspaceapps/appurl"
9290
"github.com/coder/coder/v2/codersdk"
9391
"github.com/coder/coder/v2/codersdk/drpc"
9492
"github.com/coder/coder/v2/cryptorand"
@@ -99,6 +97,7 @@ import (
9997
"github.com/coder/coder/v2/provisionersdk"
10098
sdkproto "github.com/coder/coder/v2/provisionersdk/proto"
10199
"github.com/coder/coder/v2/tailnet"
100+
"github.com/coder/pretty"
102101
"github.com/coder/retry"
103102
"github.com/coder/wgtunnel/tunnelsdk"
104103
)
@@ -434,11 +433,11 @@ func (r *RootCmd) Server(newAPI func(context.Context, *coderd.Options) (*coderd.
434433

435434
if vals.WildcardAccessURL.String() == "" {
436435
// Suffixed wildcard access URL.
437-
u, err := url.Parse(fmt.Sprintf("*--%s", tunnel.URL.Hostname()))
436+
wu := fmt.Sprintf("*--%s", tunnel.URL.Hostname())
437+
err = vals.WildcardAccessURL.Set(wu)
438438
if err != nil {
439-
return xerrors.Errorf("parse wildcard url: %w", err)
439+
return xerrors.Errorf("set wildcard access url %q: %w", wu, err)
440440
}
441-
vals.WildcardAccessURL = clibase.URL(*u)
442441
}
443442
}
444443

@@ -513,7 +512,7 @@ func (r *RootCmd) Server(newAPI func(context.Context, *coderd.Options) (*coderd.
513512
appHostname := vals.WildcardAccessURL.String()
514513
var appHostnameRegex *regexp.Regexp
515514
if appHostname != "" {
516-
appHostnameRegex, err = httpapi.CompileHostnamePattern(appHostname)
515+
appHostnameRegex, err = appurl.CompileHostnamePattern(appHostname)
517516
if err != nil {
518517
return xerrors.Errorf("parse wildcard access URL %q: %w", appHostname, err)
519518
}

cli/server_test.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ import (
2929
"time"
3030

3131
"github.com/go-chi/chi/v5"
32+
"github.com/spf13/pflag"
3233
"github.com/stretchr/testify/assert"
3334
"github.com/stretchr/testify/require"
3435
"go.uber.org/goleak"
@@ -1552,6 +1553,18 @@ func TestServer(t *testing.T) {
15521553
// ValueSource is not going to be correct on the `want`, so just
15531554
// match that field.
15541555
wantConfig.Options[i].ValueSource = gotConfig.Options[i].ValueSource
1556+
1557+
// If there is a wrapped value with a validator, unwrap it.
1558+
// The underlying doesn't compare well since it compares go pointers,
1559+
// and not the actual value.
1560+
if validator, isValidator := wantConfig.Options[i].Value.(interface{ Underlying() pflag.Value }); isValidator {
1561+
wantConfig.Options[i].Value = validator.Underlying()
1562+
}
1563+
1564+
if validator, isValidator := gotConfig.Options[i].Value.(interface{ Underlying() pflag.Value }); isValidator {
1565+
gotConfig.Options[i].Value = validator.Underlying()
1566+
}
1567+
15551568
assert.Equal(
15561569
t, wantConfig.Options[i],
15571570
gotConfig.Options[i],

cli/testdata/coder_server_--help.golden

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,7 @@ NETWORKING OPTIONS:
167167
--secure-auth-cookie bool, $CODER_SECURE_AUTH_COOKIE
168168
Controls if the 'Secure' property is set on browser session cookies.
169169

170-
--wildcard-access-url url, $CODER_WILDCARD_ACCESS_URL
170+
--wildcard-access-url string, $CODER_WILDCARD_ACCESS_URL
171171
Specifies the wildcard hostname to use for workspace applications in
172172
the form "*.example.com".
173173

cli/testdata/server-config.yaml.golden

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ networking:
44
accessURL:
55
# Specifies the wildcard hostname to use for workspace applications in the form
66
# "*.example.com".
7-
# (default: <unset>, type: url)
8-
wildcardAccessURL:
7+
# (default: <unset>, type: string)
8+
wildcardAccessURL: ""
99
# Specifies the custom docs URL.
1010
# (default: <unset>, type: url)
1111
docsURL:

coderd/agentapi/manifest.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ import (
2020
"github.com/coder/coder/v2/coderd/database/db2sdk"
2121
"github.com/coder/coder/v2/coderd/database/dbauthz"
2222
"github.com/coder/coder/v2/coderd/externalauth"
23-
"github.com/coder/coder/v2/coderd/httpapi"
23+
"github.com/coder/coder/v2/coderd/workspaceapps/appurl"
2424
"github.com/coder/coder/v2/codersdk"
2525
"github.com/coder/coder/v2/tailnet"
2626
)
@@ -108,7 +108,7 @@ func (a *ManifestAPI) GetManifest(ctx context.Context, _ *agentproto.GetManifest
108108
return nil, xerrors.Errorf("fetching workspace agent data: %w", err)
109109
}
110110

111-
appHost := httpapi.ApplicationURL{
111+
appHost := appurl.ApplicationURL{
112112
AppSlugOrPort: "{{port}}",
113113
AgentName: workspaceAgent.Name,
114114
WorkspaceName: workspace.Name,

coderd/apidoc/docs.go

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

coderd/apidoc/swagger.json

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

coderd/coderd.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ type Options struct {
9696
// E.g. "*.apps.coder.com" or "*-apps.coder.com".
9797
AppHostname string
9898
// AppHostnameRegex contains the regex version of options.AppHostname as
99-
// generated by httpapi.CompileHostnamePattern(). It MUST be set if
99+
// generated by appurl.CompileHostnamePattern(). It MUST be set if
100100
// options.AppHostname is set.
101101
AppHostnameRegex *regexp.Regexp
102102
Logger slog.Logger

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy