Skip to content

Commit 9d5a6bf

Browse files
authored
feat(edge_services) add edit mode for route rules (#5316)
1 parent 8eee6be commit 9d5a6bf

File tree

6 files changed

+227
-0
lines changed

6 files changed

+227
-0
lines changed
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
🎲🎲🎲 EXIT CODE: 0 🎲🎲🎲
2+
🟥🟥🟥 STDERR️️ 🟥🟥🟥️
3+
Edit all route rules of a route stage.
4+
5+
If backend-stage-id is provided, the editor will only show rule_http_match fields and the specified backend will be applied to all rules automatically.
6+
Otherwise, opens the editor with full rules including backend_stage_id for each rule.
7+
8+
USAGE:
9+
scw edge-services route-rules edit <route-stage-id ...> [arg=value ...]
10+
11+
ARGS:
12+
route-stage-id ID of the route stage to edit
13+
[backend-stage-id] ID of the backend stage to apply to all rules (simplifies editing when using a single backend)
14+
[mode=yaml] marshaling used when editing data (yaml | json)
15+
16+
FLAGS:
17+
-h, --help help for edit
18+
--list-sub-commands List all subcommands
19+
20+
GLOBAL FLAGS:
21+
-c, --config string The path to the config file
22+
-D, --debug Enable debug mode
23+
-o, --output string Output format: json or human, see 'scw help output' for more info (default "human")
24+
-p, --profile string The config profile to use
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
---
2+
version: 1
3+
interactions:
4+
- request:
5+
body: '{"access_key":"SCW7DJXHG04SGMT342RA", "secret_key":null, "description":"Generated
6+
by the Scaleway CLI", "created_at":"2025-06-27T14:00:16.810892Z", "updated_at":"2025-06-27T14:00:16.810892Z",
7+
"expires_at":null, "default_project_id":"564aa517-68b0-4fd7-8c8c-d21c4bcdcbd5",
8+
"editable":true, "deletable":true, "managed":false, "creation_ip":"130.180.219.188",
9+
"user_id":"4fcf3b56-3e90-4461-8198-dcf85c2699d6"}'
10+
form: {}
11+
headers:
12+
User-Agent:
13+
- scaleway-sdk-go/v1.0.0-beta.35.0.20251209111654-44f4a1dfc432 (go1.25.3; darwin;
14+
arm64) cli-e2e-test
15+
url: https://api.scaleway.com/iam/v1alpha1/api-keys/SCW7DJXHG04SGMT342RA
16+
method: GET
17+
response:
18+
body: '{"access_key":"SCW7DJXHG04SGMT342RA", "secret_key":null, "description":"Generated
19+
by the Scaleway CLI", "created_at":"2025-06-27T14:00:16.810892Z", "updated_at":"2025-06-27T14:00:16.810892Z",
20+
"expires_at":null, "default_project_id":"564aa517-68b0-4fd7-8c8c-d21c4bcdcbd5",
21+
"editable":true, "deletable":true, "managed":false, "creation_ip":"130.180.219.188",
22+
"user_id":"4fcf3b56-3e90-4461-8198-dcf85c2699d6"}'
23+
headers:
24+
Content-Length:
25+
- "406"
26+
Content-Security-Policy:
27+
- default-src 'none'; frame-ancestors 'none'
28+
Content-Type:
29+
- application/json
30+
Date:
31+
- Tue, 16 Dec 2025 08:05:40 GMT
32+
Server:
33+
- Scaleway API Gateway (fr-par-2;edge01)
34+
Strict-Transport-Security:
35+
- max-age=63072000
36+
X-Content-Type-Options:
37+
- nosniff
38+
X-Frame-Options:
39+
- DENY
40+
X-Request-Id:
41+
- ba6fd727-2477-4988-adf1-6e57f8878a8c
42+
status: 200 OK
43+
code: 200
44+
duration: ""

cmd/scw/testdata/test-all-usage-edge-services-route-rules-usage.golden

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ USAGE:
77

88
AVAILABLE COMMANDS:
99
add Add route rules
10+
edit Edit all route rules of a route stage
1011
list List route rules
1112
set Set route rules
1213

docs/commands/edge-services.md

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ Edge Services API
3434
- [List purge requests](#list-purge-requests)
3535
- [Route-rules management commands](#route-rules-management-commands)
3636
- [Add route rules](#add-route-rules)
37+
- [Edit all route rules of a route stage](#edit-all-route-rules-of-a-route-stage)
3738
- [List route rules](#list-route-rules)
3839
- [Set route rules](#set-route-rules)
3940
- [Route-stage management commands](#route-stage-management-commands)
@@ -647,6 +648,30 @@ scw edge-services route-rules add <route-stage-id ...> [arg=value ...]
647648

648649

649650

651+
### Edit all route rules of a route stage
652+
653+
Edit all route rules of a route stage.
654+
655+
If backend-stage-id is provided, the editor will only show rule_http_match fields and the specified backend will be applied to all rules automatically.
656+
Otherwise, opens the editor with full rules including backend_stage_id for each rule.
657+
658+
**Usage:**
659+
660+
```
661+
scw edge-services route-rules edit <route-stage-id ...> [arg=value ...]
662+
```
663+
664+
665+
**Args:**
666+
667+
| Name | | Description |
668+
|------|---|-------------|
669+
| route-stage-id | Required | ID of the route stage to edit |
670+
| backend-stage-id | | ID of the backend stage to apply to all rules (simplifies editing when using a single backend) |
671+
| mode | Default: `yaml`<br />One of: `yaml`, `json` | marshaling used when editing data |
672+
673+
674+
650675
### List route rules
651676

652677
List all route rules of an existing route stage, specified by its `route_stage_id`.

internal/namespaces/edge_services/v1beta1/custom.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,5 +7,9 @@ func GetCommands() *core.Commands {
77

88
cmds.MustFind("edge-services").Groups = []string{"network"}
99

10+
cmds.Merge(core.NewCommands(
11+
edgeServicesRouteRulesEditCommand(),
12+
))
13+
1014
return cmds
1115
}
Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
package edge_services
2+
3+
import (
4+
"context"
5+
"fmt"
6+
"reflect"
7+
8+
"github.com/scaleway/scaleway-cli/v2/core"
9+
"github.com/scaleway/scaleway-cli/v2/internal/editor"
10+
edgeservices "github.com/scaleway/scaleway-sdk-go/api/edge_services/v1beta1"
11+
"github.com/scaleway/scaleway-sdk-go/scw"
12+
)
13+
14+
var edgeServicesRouteRulesEditYamlExample = `route_rules:
15+
- rule_http_match:
16+
method_filters:
17+
- get
18+
- post
19+
path_filter:
20+
path_filter_type: regex
21+
value: ^/api/.*
22+
backend_stage_id: 11111111-1111-1111-1111-111111111111
23+
- rule_http_match:
24+
method_filters:
25+
- get
26+
path_filter:
27+
path_filter_type: regex
28+
value: ^/static/.*
29+
backend_stage_id: 11111111-1111-1111-1111-111111111111
30+
`
31+
32+
var edgeServicesRouteRulesEditYamlExampleSimple = `route_rules:
33+
- rule_http_match:
34+
method_filters:
35+
- get
36+
- post
37+
path_filter:
38+
path_filter_type: regex
39+
value: ^/api/.*
40+
- rule_http_match:
41+
method_filters:
42+
- get
43+
path_filter:
44+
path_filter_type: regex
45+
value: ^/static/.*
46+
`
47+
48+
type edgeServicesRouteRulesEditArgs struct {
49+
RouteStageID string
50+
BackendStageID *string
51+
Mode editor.MarshalMode
52+
}
53+
54+
func edgeServicesRouteRulesEditCommand() *core.Command {
55+
return &core.Command{
56+
Short: "Edit all route rules of a route stage",
57+
Long: `Edit all route rules of a route stage.
58+
59+
If backend-stage-id is provided, the editor will only show rule_http_match fields and the specified backend will be applied to all rules automatically.
60+
Otherwise, opens the editor with full rules including backend_stage_id for each rule.`,
61+
Namespace: "edge-services",
62+
Resource: "route-rules",
63+
Verb: "edit",
64+
ArgsType: reflect.TypeOf(edgeServicesRouteRulesEditArgs{}),
65+
ArgSpecs: core.ArgSpecs{
66+
{
67+
Name: "route-stage-id",
68+
Short: "ID of the route stage to edit",
69+
Required: true,
70+
Positional: true,
71+
},
72+
{
73+
Name: "backend-stage-id",
74+
Short: "ID of the backend stage to apply to all rules (simplifies editing when using a single backend)",
75+
Required: false,
76+
},
77+
editor.MarshalModeArgSpec(),
78+
},
79+
Run: func(ctx context.Context, argsI any) (i any, e error) {
80+
args := argsI.(*edgeServicesRouteRulesEditArgs)
81+
82+
client := core.ExtractClient(ctx)
83+
api := edgeservices.NewAPI(client)
84+
85+
rules, err := api.ListRouteRules(&edgeservices.ListRouteRulesRequest{
86+
RouteStageID: args.RouteStageID,
87+
}, scw.WithContext(ctx))
88+
if err != nil {
89+
return nil, fmt.Errorf("failed to list route rules: %w", err)
90+
}
91+
92+
setRequest := &edgeservices.SetRouteRulesRequest{
93+
RouteStageID: args.RouteStageID,
94+
}
95+
96+
template := edgeServicesRouteRulesEditYamlExample
97+
var ignoreFields []string
98+
if args.BackendStageID != nil {
99+
template = edgeServicesRouteRulesEditYamlExampleSimple
100+
ignoreFields = []string{"backend_stage_id"}
101+
}
102+
103+
editedSetRequest, err := editor.UpdateResourceEditor(rules, setRequest, &editor.Config{
104+
PutRequest: true,
105+
MarshalMode: args.Mode,
106+
Template: template,
107+
IgnoreFields: ignoreFields,
108+
})
109+
if err != nil {
110+
return nil, err
111+
}
112+
113+
setRequest = editedSetRequest.(*edgeservices.SetRouteRulesRequest)
114+
115+
if args.BackendStageID != nil {
116+
for _, rule := range setRequest.RouteRules {
117+
rule.BackendStageID = args.BackendStageID
118+
}
119+
}
120+
121+
resp, err := api.SetRouteRules(setRequest, scw.WithContext(ctx))
122+
if err != nil {
123+
return nil, fmt.Errorf("failed to set route rules: %w", err)
124+
}
125+
126+
return resp.RouteRules, nil
127+
},
128+
}
129+
}

0 commit comments

Comments
 (0)