go.ligato.io/vpp-agent/v3@v3.5.0/cmd/agentctl/commands/values.go (about) 1 // Copyright (c) 2019 Cisco and/or its affiliates. 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 commands 16 17 import ( 18 "context" 19 "fmt" 20 "io" 21 "strings" 22 "text/tabwriter" 23 24 "github.com/spf13/cobra" 25 26 "go.ligato.io/vpp-agent/v3/cmd/agentctl/api/types" 27 agentcli "go.ligato.io/vpp-agent/v3/cmd/agentctl/cli" 28 "go.ligato.io/vpp-agent/v3/pkg/models" 29 "go.ligato.io/vpp-agent/v3/proto/ligato/kvscheduler" 30 ) 31 32 func NewValuesCommand(cli agentcli.Cli) *cobra.Command { 33 var opts ValuesOptions 34 cmd := &cobra.Command{ 35 Use: "values [MODEL]", 36 Short: "Retrieve values from scheduler", 37 Args: cobra.RangeArgs(0, 1), 38 RunE: func(cmd *cobra.Command, args []string) error { 39 opts.Models = args 40 return runValues(cli, opts) 41 }, 42 } 43 flags := cmd.Flags() 44 flags.StringVarP(&opts.Format, "format", "f", "", "Format output") 45 return cmd 46 } 47 48 type ValuesOptions struct { 49 Models []string 50 Format string 51 } 52 53 func runValues(cli agentcli.Cli, opts ValuesOptions) error { 54 var model string 55 if len(opts.Models) > 0 { 56 model = opts.Models[0] 57 } 58 59 ctx, cancel := context.WithCancel(context.Background()) 60 defer cancel() 61 62 allModels, err := cli.Client().ModelList(ctx, types.ModelListOptions{ 63 Class: "config", 64 }) 65 if err != nil { 66 return err 67 } 68 69 var modelKeyPrefix string 70 for _, m := range allModels { 71 if model == m.Name { 72 modelKeyPrefix = m.KeyPrefix 73 break 74 } 75 } 76 77 values, err := cli.Client().SchedulerValues(ctx, types.SchedulerValuesOptions{ 78 KeyPrefix: modelKeyPrefix, 79 }) 80 if err != nil { 81 return err 82 } 83 84 format := opts.Format 85 if len(format) == 0 { 86 printValuesTable(cli.Out(), values) 87 } else { 88 if err := formatAsTemplate(cli.Out(), format, values); err != nil { 89 return err 90 } 91 } 92 93 return nil 94 } 95 96 // printValuesTable prints values data using table format 97 func printValuesTable(out io.Writer, status []*kvscheduler.BaseValueStatus) { 98 w := tabwriter.NewWriter(out, 10, 0, 3, ' ', 0) 99 defer w.Flush() 100 101 fmt.Fprintf(w, "MODEL\tNAME\tSTATE\tDETAILS\tLAST OP\tERROR\t\n") 102 103 var printVal = func(val *kvscheduler.ValueStatus) { 104 var ( 105 model string 106 name string 107 ) 108 109 m, err := models.GetModelForKey(val.Key) 110 if err != nil { 111 name = val.Key 112 } else { 113 model = m.Spec().ModelName() 114 name = m.StripKeyPrefix(val.Key) 115 } 116 117 var lastOp string 118 if val.LastOperation != kvscheduler.TxnOperation_UNDEFINED { 119 lastOp = val.LastOperation.String() 120 } 121 state := val.State.String() 122 if val.State == kvscheduler.ValueState_OBTAINED { 123 state = strings.ToLower(state) 124 } 125 126 var details string 127 if len(val.Details) > 0 { 128 details = strings.Join(val.Details, ", ") 129 } 130 131 fmt.Fprintf(w, "%s\t%s\t%s\t%s\t%s\t%s\t\n", model, name, state, details, lastOp, val.Error) 132 } 133 134 for _, d := range status { 135 printVal(d.Value) 136 for _, v := range d.DerivedValues { 137 printVal(v) 138 } 139 } 140 }