Skip to content

Commit 101113e

Browse files
committed
cmd/incusd: introduce SuffixActions for solving routing conflicts
Signed-off-by: 0xk1f0 <[email protected]>
1 parent 4c4e778 commit 101113e

File tree

3 files changed

+65
-47
lines changed

3 files changed

+65
-47
lines changed

cmd/incusd/api_1.0.go

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -76,10 +76,7 @@ var api10 = []APIEndpoint{
7676
imageAliasCmd,
7777
imageAliasesCmd,
7878
imageCmd,
79-
imageExportCmd,
80-
imageRefreshCmd,
8179
imagesCmd,
82-
imageSecretCmd,
8380
metadataConfigurationCmd,
8481
networkCmd,
8582
networkLeasesCmd,

cmd/incusd/daemon.go

Lines changed: 40 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -228,15 +228,27 @@ func defaultDaemon() *Daemon {
228228

229229
// APIEndpoint represents a URL in our API.
230230
type APIEndpoint struct {
231-
Name string // Name for this endpoint.
232-
Path string // Path pattern for this endpoint.
233-
Aliases []APIEndpointAlias // Any aliases for this endpoint.
234-
Get APIEndpointAction
235-
Head APIEndpointAction
236-
Put APIEndpointAction
237-
Post APIEndpointAction
238-
Delete APIEndpointAction
239-
Patch APIEndpointAction
231+
Name string // Name for this endpoint.
232+
Path string // Path pattern for this endpoint.
233+
Aliases []APIEndpointAlias // Any aliases for this endpoint.
234+
SuffixActions []APIEndpointSuffixAction
235+
Get APIEndpointAction
236+
Head APIEndpointAction
237+
Put APIEndpointAction
238+
Post APIEndpointAction
239+
Delete APIEndpointAction
240+
Patch APIEndpointAction
241+
}
242+
243+
// APIEndpointSuffixAction represents actions appended to the end of the path like `/1.0/endpoint/action`
244+
type APIEndpointSuffixAction struct {
245+
Name string
246+
Get APIEndpointAction
247+
Head APIEndpointAction
248+
Put APIEndpointAction
249+
Post APIEndpointAction
250+
Delete APIEndpointAction
251+
Patch APIEndpointAction
240252
}
241253

242254
// APIEndpointAlias represents an alias URL of and APIEndpoint in our API.
@@ -618,20 +630,32 @@ func (d *Daemon) State() *state.State {
618630
}
619631
}
620632

621-
func (d *Daemon) createCmd(restAPI *http.ServeMux, version string, c APIEndpoint) {
633+
func (d *Daemon) createCmd(restAPI *http.ServeMux, apiVersion string, c APIEndpoint) {
622634
var uri string
623635
if c.Path == "" {
624-
uri = fmt.Sprintf("/%s", version)
625-
} else if version != "" {
626-
uri = fmt.Sprintf("/%s/%s", version, c.Path)
636+
uri = fmt.Sprintf("/%s", apiVersion)
637+
} else if apiVersion != "" {
638+
uri = fmt.Sprintf("/%s/%s", apiVersion, c.Path)
627639
} else {
628640
uri = fmt.Sprintf("/%s", c.Path)
629641
}
630642

631643
restAPI.HandleFunc(uri, func(w http.ResponseWriter, r *http.Request) {
632644
w.Header().Set("Content-Type", "application/json")
633645

634-
if !(r.RemoteAddr == "@" && version == "internal") {
646+
for _, action := range c.SuffixActions {
647+
if strings.HasSuffix(r.URL.Path, action.Name) {
648+
c.Get = action.Get
649+
c.Post = action.Post
650+
c.Put = action.Put
651+
c.Patch = action.Patch
652+
c.Delete = action.Delete
653+
c.Head = action.Head
654+
break
655+
}
656+
}
657+
658+
if !(r.RemoteAddr == "@" && apiVersion == "internal") {
635659
// Block public API requests until we're done with basic
636660
// initialization tasks, such setting up the cluster database.
637661
select {
@@ -659,7 +683,7 @@ func (d *Daemon) createCmd(restAPI *http.ServeMux, version string, c APIEndpoint
659683
}
660684

661685
// Reject internal queries to remote, non-cluster, clients
662-
if version == "internal" && !slices.Contains([]string{"unix", "cluster"}, protocol) {
686+
if apiVersion == "internal" && !slices.Contains([]string{"unix", "cluster"}, protocol) {
663687
// Except for the initial cluster accept request (done over trusted TLS)
664688
if !trusted || c.Path != "cluster/accept" || protocol != api.AuthenticationMethodTLS {
665689
logger.Warn("Rejecting remote internal API request", logger.Ctx{"ip": r.RemoteAddr})
@@ -730,7 +754,7 @@ func (d *Daemon) createCmd(restAPI *http.ServeMux, version string, c APIEndpoint
730754
// - /1.0/operations endpoints
731755
// - GET queries
732756
allowedDuringShutdown := func() bool {
733-
if version == "internal" {
757+
if apiVersion == "internal" {
734758
return true
735759
}
736760

cmd/incusd/images.go

Lines changed: 25 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -69,34 +69,6 @@ var imagesCmd = APIEndpoint{
6969
Post: APIEndpointAction{Handler: imagesPost, AllowUntrusted: true},
7070
}
7171

72-
var imageCmd = APIEndpoint{
73-
Path: "images/{fingerprint}",
74-
75-
Delete: APIEndpointAction{Handler: imageDelete, AccessHandler: allowPermission(auth.ObjectTypeImage, auth.EntitlementCanEdit, "fingerprint")},
76-
Get: APIEndpointAction{Handler: imageGet, AllowUntrusted: true},
77-
Patch: APIEndpointAction{Handler: imagePatch, AccessHandler: allowPermission(auth.ObjectTypeImage, auth.EntitlementCanEdit, "fingerprint")},
78-
Put: APIEndpointAction{Handler: imagePut, AccessHandler: allowPermission(auth.ObjectTypeImage, auth.EntitlementCanEdit, "fingerprint")},
79-
}
80-
81-
var imageExportCmd = APIEndpoint{
82-
Path: "images/{fingerprint}/export",
83-
84-
Get: APIEndpointAction{Handler: imageExport, AllowUntrusted: true},
85-
Post: APIEndpointAction{Handler: imageExportPost, AccessHandler: allowPermission(auth.ObjectTypeImage, auth.EntitlementCanEdit, "fingerprint")},
86-
}
87-
88-
var imageSecretCmd = APIEndpoint{
89-
Path: "images/{fingerprint}/secret",
90-
91-
Post: APIEndpointAction{Handler: imageSecret, AccessHandler: allowPermission(auth.ObjectTypeImage, auth.EntitlementCanEdit, "fingerprint")},
92-
}
93-
94-
var imageRefreshCmd = APIEndpoint{
95-
Path: "images/{fingerprint}/refresh",
96-
97-
Post: APIEndpointAction{Handler: imageRefresh, AccessHandler: allowPermission(auth.ObjectTypeImage, auth.EntitlementCanEdit, "fingerprint")},
98-
}
99-
10072
var imageAliasesCmd = APIEndpoint{
10173
Path: "images/aliases",
10274

@@ -114,6 +86,31 @@ var imageAliasCmd = APIEndpoint{
11486
Put: APIEndpointAction{Handler: imageAliasPut, AccessHandler: allowPermission(auth.ObjectTypeImageAlias, auth.EntitlementCanEdit, "name")},
11587
}
11688

89+
var imageCmd = APIEndpoint{
90+
Path: "images/{fingerprint}/",
91+
92+
Delete: APIEndpointAction{Handler: imageDelete, AccessHandler: allowPermission(auth.ObjectTypeImage, auth.EntitlementCanEdit, "fingerprint")},
93+
Get: APIEndpointAction{Handler: imageGet, AllowUntrusted: true},
94+
Patch: APIEndpointAction{Handler: imagePatch, AccessHandler: allowPermission(auth.ObjectTypeImage, auth.EntitlementCanEdit, "fingerprint")},
95+
Put: APIEndpointAction{Handler: imagePut, AccessHandler: allowPermission(auth.ObjectTypeImage, auth.EntitlementCanEdit, "fingerprint")},
96+
97+
SuffixActions: []APIEndpointSuffixAction{
98+
APIEndpointSuffixAction{
99+
Name: "/export",
100+
Get: APIEndpointAction{Handler: imageExport, AllowUntrusted: true},
101+
Post: APIEndpointAction{Handler: imageExportPost, AccessHandler: allowPermission(auth.ObjectTypeImage, auth.EntitlementCanEdit, "fingerprint")},
102+
},
103+
APIEndpointSuffixAction{
104+
Name: "/secret",
105+
Post: APIEndpointAction{Handler: imageSecret, AccessHandler: allowPermission(auth.ObjectTypeImage, auth.EntitlementCanEdit, "fingerprint")},
106+
},
107+
APIEndpointSuffixAction{
108+
Name: "/refresh",
109+
Post: APIEndpointAction{Handler: imageRefresh, AccessHandler: allowPermission(auth.ObjectTypeImage, auth.EntitlementCanEdit, "fingerprint")},
110+
},
111+
},
112+
}
113+
117114
/*
118115
We only want a single publish running at any one time.
119116

0 commit comments

Comments
 (0)