Skip to content

Commit b6e5580

Browse files
author
Marc Odermatt
committed
global desc lookup
1 parent 35d3ddd commit b6e5580

File tree

2 files changed

+98
-20
lines changed

2 files changed

+98
-20
lines changed

scion/cmd/scion/fabrid.go

+26-10
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import (
1818
"context"
1919
"fmt"
2020
"net"
21+
"strconv"
2122
"time"
2223

2324
"github.com/scionproto/scion/pkg/addr"
@@ -46,7 +47,7 @@ func newFabrid(pather CommandPather) *cobra.Command {
4647
var cmd = &cobra.Command{
4748
Use: "fabrid",
4849
Short: "Display FABRID policy information",
49-
Args: cobra.ExactArgs(1),
50+
Args: cobra.RangeArgs(1, 2),
5051
Example: fmt.Sprintf(` %[1]s showpaths 1-ff00:0:110 --extended
5152
%[1]s showpaths 1-ff00:0:110 --local 127.0.0.55 --json
5253
%[1]s showpaths 1-ff00:0:111 --sequence="0-0#2 0*" # outgoing IfID=2
@@ -56,10 +57,6 @@ func newFabrid(pather CommandPather) *cobra.Command {
5657
Long: `'fabrid' lists available policies at a remote AS, or shows the
5758
description of a specific policy.`,
5859
RunE: func(cmd *cobra.Command, args []string) error {
59-
dst, err := addr.ParseIA(args[0])
60-
if err != nil {
61-
return serrors.WrapStr("invalid destination ISD-AS", err)
62-
}
6360
if err := app.SetupLog(flags.logLevel); err != nil {
6461
return serrors.WrapStr("setting up logging", err)
6562
}
@@ -87,16 +84,35 @@ description of a specific policy.`,
8784
)
8885

8986
span, traceCtx := tracing.CtxWith(context.Background(), "run")
90-
span.SetTag("dst.isd_as", dst)
9187
defer span.Finish()
9288

9389
ctx, cancel := context.WithTimeout(traceCtx, flags.timeout)
9490
defer cancel()
95-
res, err := fabrid.Run(ctx, dst, flags.cfg)
96-
if err != nil {
97-
return err
91+
if len(args) == 1 {
92+
identifier, err := strconv.ParseUint(args[0], 10, 32)
93+
if err != nil {
94+
return serrors.WrapStr("invalid policy identifier", err)
95+
}
96+
_, err = fabrid.Run(ctx, nil, uint32(identifier), flags.cfg)
97+
if err != nil {
98+
return err
99+
}
100+
101+
} else if len(args) == 2 {
102+
dst, err := addr.ParseIA(args[0])
103+
if err != nil {
104+
return serrors.WrapStr("invalid destination ISD-AS", err)
105+
}
106+
identifier, err := strconv.ParseUint(args[1], 10, 32)
107+
if err != nil {
108+
return serrors.WrapStr("invalid policy identifier", err)
109+
}
110+
_, err = fabrid.Run(ctx, &dst, uint32(identifier), flags.cfg)
111+
if err != nil {
112+
return err
113+
}
114+
span.SetTag("dst.isd_as", dst)
98115
}
99-
fmt.Println(res.Destination, res.Description)
100116
switch flags.format {
101117
case "human":
102118
return nil

scion/fabrid/fabrid.go

+72-10
Original file line numberDiff line numberDiff line change
@@ -16,30 +16,92 @@ package fabrid
1616

1717
import (
1818
"context"
19+
"encoding/json"
1920
"fmt"
2021
"github.com/scionproto/scion/pkg/addr"
2122
"github.com/scionproto/scion/pkg/daemon"
2223
"github.com/scionproto/scion/pkg/private/serrors"
24+
"io/ioutil"
25+
"net/http"
2326
)
2427

2528
// Result contains all the discovered paths.
2629
type Result struct {
27-
Destination addr.IA `json:"destination" yaml:"destination"`
28-
Description string `json:"description,omitempty" yaml:"description,omitempty"`
30+
Destination *addr.IA `json:"destination" yaml:"destination"`
31+
Description string `json:"description,omitempty" yaml:"description,omitempty"`
2932
}
3033

3134
// Run lists information for FABRID policies to stdout.
32-
func Run(ctx context.Context, dst addr.IA, cfg Config) (*Result, error) {
33-
sdConn, err := daemon.NewService(cfg.Daemon).Connect(ctx)
35+
func Run(ctx context.Context, dst *addr.IA, identifier uint32, cfg Config) (*Result, error) {
36+
var description string
37+
if dst != nil {
38+
sdConn, err := daemon.NewService(cfg.Daemon).Connect(ctx)
39+
if err != nil {
40+
return nil, serrors.WrapStr("connecting to the SCION Daemon", err, "addr", cfg.Daemon)
41+
}
42+
defer sdConn.Close()
43+
44+
description, err = sdConn.RemotePolicyDescription(ctx, identifier, *dst)
45+
if err != nil {
46+
return nil, serrors.WrapStr("retrieving description from the SCION Daemon", err)
47+
}
48+
} else {
49+
// Replace with the raw URL of your GitHub content (e.g., https://raw.githubusercontent.com/user/repo/branch/path/to/policies.json)
50+
globalPolicyURL := "https://raw.githubusercontent.com/marcodermatt/fabrid-global-policies/main/policy-descriptions.json"
51+
52+
// Fetch the global policy from the URL
53+
policy, err := FetchGlobalPolicy(globalPolicyURL)
54+
if err != nil {
55+
return nil, serrors.WrapStr("fetching global policy", err)
56+
}
57+
58+
// Retrieve the description for the given identifier
59+
description, err = GetPolicyDescription(policy, identifier)
60+
if err != nil {
61+
return nil, serrors.WrapStr("getting global policy description", err)
62+
}
63+
64+
}
65+
// Output the description
66+
fmt.Printf("Policy %d: %s\n", identifier, description)
67+
return &Result{Destination: dst, Description: description}, nil
68+
}
69+
70+
// GlobalPolicy holds the mapping of uint32 identifiers to their string descriptions
71+
type GlobalPolicy map[uint32]string
72+
73+
// FetchGlobalPolicy fetches and parses the global policy from the given URL
74+
func FetchGlobalPolicy(url string) (GlobalPolicy, error) {
75+
resp, err := http.Get(url)
3476
if err != nil {
35-
return nil, serrors.WrapStr("connecting to the SCION Daemon", err, "addr", cfg.Daemon)
77+
return nil, serrors.WrapStr("failed to fetch global policy", err)
3678
}
37-
defer sdConn.Close()
79+
defer resp.Body.Close()
3880

39-
description, err := sdConn.RemotePolicyDescription(ctx, 10, dst)
81+
if resp.StatusCode != http.StatusOK {
82+
return nil, serrors.New("failed to fetch global policy", "StatusCode", resp.StatusCode)
83+
}
84+
85+
// Read the response body
86+
body, err := ioutil.ReadAll(resp.Body)
4087
if err != nil {
41-
return nil, serrors.WrapStr("retrieving description from the SCION Daemon", err)
88+
return nil, serrors.WrapStr("failed to read response body", err)
4289
}
43-
fmt.Println(description)
44-
return &Result{Destination: dst, Description: description}, nil
90+
91+
// Unmarshal the JSON data into a map
92+
var policy GlobalPolicy
93+
if err = json.Unmarshal(body, &policy); err != nil {
94+
return nil, serrors.WrapStr("failed to unmarshal policy JSON", err)
95+
}
96+
97+
return policy, nil
98+
}
99+
100+
// GetPolicyDescription retrieves the description for the given identifier
101+
func GetPolicyDescription(policy GlobalPolicy, identifier uint32) (string, error) {
102+
description, exists := policy[identifier]
103+
if !exists {
104+
return "", serrors.New("no policy found", "identifier", identifier)
105+
}
106+
return description, nil
45107
}

0 commit comments

Comments
 (0)