|
| 1 | +// Copyright 2020 Anapaya Systems |
| 2 | +// |
| 3 | +// Licensed under the Apache License, Version 2.0 (the "License"); |
| 4 | +// you may not use this file except in compliance with the License. |
| 5 | +// You may obtain a copy of the License at |
| 6 | +// |
| 7 | +// http://www.apache.org/licenses/LICENSE-2.0 |
| 8 | +// |
| 9 | +// Unless required by applicable law or agreed to in writing, software |
| 10 | +// distributed under the License is distributed on an "AS IS" BASIS, |
| 11 | +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 12 | +// See the License for the specific language governing permissions and |
| 13 | +// limitations under the License. |
| 14 | + |
| 15 | +package main |
| 16 | + |
| 17 | +import ( |
| 18 | + "context" |
| 19 | + "fmt" |
| 20 | + "net" |
| 21 | + "time" |
| 22 | + |
| 23 | + "github.com/scionproto/scion/pkg/addr" |
| 24 | + "github.com/scionproto/scion/pkg/log" |
| 25 | + "github.com/scionproto/scion/pkg/private/serrors" |
| 26 | + "github.com/scionproto/scion/private/app" |
| 27 | + "github.com/scionproto/scion/private/app/flag" |
| 28 | + "github.com/scionproto/scion/private/tracing" |
| 29 | + "github.com/scionproto/scion/scion/fabrid" |
| 30 | + "github.com/spf13/cobra" |
| 31 | +) |
| 32 | + |
| 33 | +func newFabrid(pather CommandPather) *cobra.Command { |
| 34 | + var envFlags flag.SCIONEnvironment |
| 35 | + var flags struct { |
| 36 | + timeout time.Duration |
| 37 | + cfg fabrid.Config |
| 38 | + extended bool |
| 39 | + json bool |
| 40 | + logLevel string |
| 41 | + noColor bool |
| 42 | + tracer string |
| 43 | + format string |
| 44 | + } |
| 45 | + |
| 46 | + var cmd = &cobra.Command{ |
| 47 | + Use: "fabrid", |
| 48 | + Short: "Display FABRID policy information", |
| 49 | + Args: cobra.ExactArgs(1), |
| 50 | + Example: fmt.Sprintf(` %[1]s showpaths 1-ff00:0:110 --extended |
| 51 | + %[1]s showpaths 1-ff00:0:110 --local 127.0.0.55 --json |
| 52 | + %[1]s showpaths 1-ff00:0:111 --sequence="0-0#2 0*" # outgoing IfID=2 |
| 53 | + %[1]s showpaths 1-ff00:0:111 --sequence="0* 0-0#41" # incoming IfID=41 at dstIA |
| 54 | + %[1]s showpaths 1-ff00:0:111 --sequence="0* 1-ff00:0:112 0*" # 1-ff00:0:112 on the path |
| 55 | + %[1]s showpaths 1-ff00:0:110 --no-probe`, pather.CommandPath()), |
| 56 | + Long: `'fabrid' lists available policies at a remote AS, or shows the |
| 57 | +description of a specific policy.`, |
| 58 | + 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 | + } |
| 63 | + if err := app.SetupLog(flags.logLevel); err != nil { |
| 64 | + return serrors.WrapStr("setting up logging", err) |
| 65 | + } |
| 66 | + closer, err := setupTracer("fabrid", flags.tracer) |
| 67 | + if err != nil { |
| 68 | + return serrors.WrapStr("setting up tracing", err) |
| 69 | + } |
| 70 | + defer closer() |
| 71 | + |
| 72 | + if flags.json && !cmd.Flags().Lookup("format").Changed { |
| 73 | + flags.format = "json" |
| 74 | + } |
| 75 | + printf, err := getPrintf(flags.format, cmd.OutOrStdout()) |
| 76 | + if err != nil { |
| 77 | + return serrors.WrapStr("get formatting", err) |
| 78 | + } |
| 79 | + |
| 80 | + cmd.SilenceUsage = true |
| 81 | + |
| 82 | + if err := envFlags.LoadExternalVars(); err != nil { |
| 83 | + return err |
| 84 | + } |
| 85 | + |
| 86 | + flags.cfg.Daemon = envFlags.Daemon() |
| 87 | + flags.cfg.Local = net.IP(envFlags.Local().AsSlice()) |
| 88 | + log.Debug("Resolved SCION environment flags", |
| 89 | + "daemon", flags.cfg.Daemon, |
| 90 | + "local", flags.cfg.Local, |
| 91 | + ) |
| 92 | + |
| 93 | + span, traceCtx := tracing.CtxWith(context.Background(), "run") |
| 94 | + span.SetTag("dst.isd_as", dst) |
| 95 | + defer span.Finish() |
| 96 | + |
| 97 | + ctx, cancel := context.WithTimeout(traceCtx, flags.timeout) |
| 98 | + defer cancel() |
| 99 | + res, err := fabrid.Run(ctx, dst, flags.cfg) |
| 100 | + if err != nil { |
| 101 | + return err |
| 102 | + } |
| 103 | + |
| 104 | + switch flags.format { |
| 105 | + case "human": |
| 106 | + if res.IsLocal() { |
| 107 | + printf("Empty path, destination is local AS %s\n", res.Destination) |
| 108 | + return nil |
| 109 | + } |
| 110 | + printf("Available policies at %s\n", res.Destination) |
| 111 | + if len(res.Paths) == 0 { |
| 112 | + return app.WithExitCode(serrors.New("no policies found"), 1) |
| 113 | + } |
| 114 | + res.Human(cmd.OutOrStdout(), flags.extended, !flags.noColor) |
| 115 | + case "json": |
| 116 | + return serrors.New("Not implemented", "format", flags.format) |
| 117 | + case "yaml": |
| 118 | + return serrors.New("Not implemented", "format", flags.format) |
| 119 | + default: |
| 120 | + return serrors.New("output format not supported", "format", flags.format) |
| 121 | + } |
| 122 | + return nil |
| 123 | + }, |
| 124 | + } |
| 125 | + |
| 126 | + envFlags.Register(cmd.Flags()) |
| 127 | + cmd.Flags().DurationVar(&flags.timeout, "timeout", 5*time.Second, "Timeout") |
| 128 | + cmd.Flags().StringVar(&flags.cfg.Sequence, "sequence", "", app.SequenceUsage) |
| 129 | + cmd.Flags().IntVarP(&flags.cfg.MaxPaths, "maxpaths", "m", 10, |
| 130 | + "Maximum number of paths that are displayed") |
| 131 | + cmd.Flags().BoolVarP(&flags.extended, "extended", "e", false, |
| 132 | + "Show extended path meta data information") |
| 133 | + cmd.Flags().BoolVarP(&flags.cfg.Refresh, "refresh", "r", false, |
| 134 | + "Set refresh flag for SCION Daemon path request") |
| 135 | + cmd.Flags().BoolVar(&flags.cfg.NoProbe, "no-probe", false, |
| 136 | + "Do not probe the paths and print the health status") |
| 137 | + cmd.Flags().BoolVarP(&flags.json, "json", "j", false, |
| 138 | + "Write the output as machine readable json") |
| 139 | + cmd.Flags().StringVar(&flags.format, "format", "human", |
| 140 | + "Specify the output format (human|json|yaml)") |
| 141 | + cmd.Flags().BoolVar(&flags.noColor, "no-color", false, "disable colored output") |
| 142 | + cmd.Flags().StringVar(&flags.logLevel, "log.level", "", app.LogLevelUsage) |
| 143 | + cmd.Flags().StringVar(&flags.tracer, "tracing.agent", "", "Tracing agent address") |
| 144 | + cmd.Flags().BoolVar(&flags.cfg.Epic, "epic", false, "Enable EPIC.") |
| 145 | + err := cmd.Flags().MarkDeprecated("json", "json flag is deprecated, use format flag") |
| 146 | + if err != nil { |
| 147 | + panic(err) |
| 148 | + } |
| 149 | + return cmd |
| 150 | +} |
0 commit comments