go.ligato.io/vpp-agent/v3@v3.5.0/examples/kvscheduler/mock_plugins/scenario/scenario.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 scenario 16 17 import ( 18 "bufio" 19 "fmt" 20 "log" 21 "os" 22 "strings" 23 "time" 24 25 "go.ligato.io/vpp-agent/v3/client" 26 kvs "go.ligato.io/vpp-agent/v3/plugins/kvscheduler/api" 27 "go.ligato.io/vpp-agent/v3/proto/ligato/kvscheduler" 28 ) 29 30 const graphURL = "http://localhost:9191/scheduler/graph" 31 32 const ( 33 InfoMsgColor = "\033[1;34m%s\033[0m\n" 34 NoticeMsgColor = "\033[1;35m%s\033[0m\n" 35 NotifMsgColor = "\033[1;33m%s\033[0m\n" 36 ErrorMsgColor = "\033[1;31m%s\033[0m\n" 37 InputReqMsgColor = "\033[0;32m%s\033[0m\n" 38 DebugMsgColor = "\033[0;36m%s\033[0m\n" 39 ) 40 41 // Run runs a scenario selected by the user. 42 func Run(kv kvs.KVScheduler, setLogging func(debugMode bool)) { 43 time.Sleep(300 * time.Millisecond) // give agent logs time to get printed 44 defer func() { 45 fmt.Printf(InfoMsgColor, "The example scenario has finalized, the agent can be now terminated with CTRL-C.") 46 fmt.Printf(InfoMsgColor, "But while the agent is still running, the REST API of KVScheduler can be explored.") 47 fmt.Printf(InfoMsgColor, "Learn more from docs/kvscheduler/kvscheduler.md, section \"REST API\"") 48 }() 49 50 // let the user to select the scenario to run 51 scenarioFnc := func() {} 52 debugLog := true 53 scanner := bufio.NewScanner(os.Stdin) 54 fmt.Println("") 55 fmt.Printf(InputReqMsgColor, "Please select the example scenario to run: ") 56 fmt.Printf(InputReqMsgColor, "1) BD-interface binding and FIB are pending after the first resync, but become ready after an update") 57 fmt.Printf(InputReqMsgColor, "2) BD-interface binding and FIB are unconfigured and set as pending after an update") 58 fmt.Printf(InputReqMsgColor, "3) Update transaction with invalid interface MAC address is reverted") 59 fmt.Printf(InputReqMsgColor, "4) Invalid interface configuration fixed in the next Update transaction") 60 fmt.Printf(InputReqMsgColor, "5) Change of the interface type performed via re-creation") 61 fmt.Printf(InputReqMsgColor, "6) Failed interface creation fixed by subsequent Retry") 62 fmt.Printf(InputReqMsgColor, "7) Run performance test") 63 inputLoop: 64 for { 65 fmt.Print("--> ") 66 scanner.Scan() 67 input := scanner.Text() 68 switch input { 69 case "1": 70 scenarioFnc = PendingAfterResync 71 break inputLoop 72 case "2": 73 scenarioFnc = PendingAfterChange 74 break inputLoop 75 case "3": 76 scenarioFnc = RevertedChange 77 break inputLoop 78 case "4": 79 scenarioFnc = InvalidConfigFixedWithUpdate 80 break inputLoop 81 case "5": 82 scenarioFnc = InterfaceRecreation 83 break inputLoop 84 case "6": 85 scenarioFnc = FailureFixedWithRetry 86 break inputLoop 87 case "7": 88 debugLog = false 89 scenarioFnc = PerfTest 90 break inputLoop 91 default: 92 fmt.Printf(ErrorMsgColor, "Invalid option!") 93 continue 94 } 95 } 96 97 setLogging(debugLog) 98 if debugLog { 99 // watch and inform about value status updates 100 ch := make(chan *kvscheduler.BaseValueStatus, 100) 101 kv.WatchValueStatus(ch, nil) 102 go watchValueStatus(ch) 103 } 104 105 // start the selected scenario 106 scenarioFnc() 107 } 108 109 // watchValueStatus informs about value status updates. 110 func watchValueStatus(ch <-chan *kvscheduler.BaseValueStatus) { 111 for { 112 select { 113 case status := <-ch: 114 fmt.Printf(NotifMsgColor, 115 fmt.Sprintf("Value status change: %v", status.String())) 116 } 117 } 118 } 119 120 // listKnownModels prints information about every registered model - in the case 121 // of this example, we have a model for interfaces, defined in ifplugin/model, 122 // and models for BDs and FIBs, defined under l2plugin/model. 123 func listKnownModels(c client.ConfigClient) { 124 knownModels, err := c.KnownModels("config") 125 if err != nil { 126 log.Fatalln(err) 127 } 128 fmt.Printf(DebugMsgColor, 129 fmt.Sprintf("Listing %d known models...", len(knownModels))) 130 for _, model := range knownModels { 131 fmt.Printf(DebugMsgColor, fmt.Sprintf(" - %v\n", model.String())) 132 } 133 time.Sleep(time.Second * 2) 134 } 135 136 func printMessage(lines ...string) { 137 border := strings.Repeat("~", 80) 138 fmt.Printf(InfoMsgColor, border) 139 for _, line := range lines { 140 fmt.Printf(InfoMsgColor, fmt.Sprintf("| %-76s |", line)) 141 } 142 fmt.Printf(InfoMsgColor, border) 143 time.Sleep(time.Second * 2) 144 } 145 146 func informAboutGraphURL(txnNum int, afterResync bool, sleep bool) { 147 txnType := "data-update txn" 148 if afterResync { 149 txnType = "resync txn" 150 } 151 msg := fmt.Sprintf("Graph state after %s can be displayed at URL: %s?txn=%d\n", 152 txnType, graphURL, txnNum) 153 fmt.Printf(NoticeMsgColor, msg) 154 if sleep { 155 time.Sleep(time.Second * 5) 156 } 157 }