github.com/sberex/go-sberex@v1.8.2-0.20181113200658-ed96ac38f7d7/cmd/puppeth/wizard_network.go (about) 1 // This file is part of the go-sberex library. The go-sberex library is 2 // free software: you can redistribute it and/or modify it under the terms 3 // of the GNU Lesser General Public License as published by the Free 4 // Software Foundation, either version 3 of the License, or (at your option) 5 // any later version. 6 // 7 // The go-sberex library is distributed in the hope that it will be useful, 8 // but WITHOUT ANY WARRANTY; without even the implied warranty of 9 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser 10 // General Public License <http://www.gnu.org/licenses/> for more details. 11 12 package main 13 14 import ( 15 "fmt" 16 "strings" 17 18 "github.com/Sberex/go-sberex/log" 19 ) 20 21 // manageServers displays a list of servers the user can disconnect from, and an 22 // option to connect to new servers. 23 func (w *wizard) manageServers() { 24 // List all the servers we can disconnect, along with an entry to connect a new one 25 fmt.Println() 26 27 servers := w.conf.servers() 28 for i, server := range servers { 29 fmt.Printf(" %d. Disconnect %s\n", i+1, server) 30 } 31 fmt.Printf(" %d. Connect another server\n", len(w.conf.Servers)+1) 32 33 choice := w.readInt() 34 if choice < 0 || choice > len(w.conf.Servers)+1 { 35 log.Error("Invalid server choice, aborting") 36 return 37 } 38 // If the user selected an existing server, drop it 39 if choice <= len(w.conf.Servers) { 40 server := servers[choice-1] 41 client := w.servers[server] 42 43 delete(w.servers, server) 44 if client != nil { 45 client.Close() 46 } 47 delete(w.conf.Servers, server) 48 w.conf.flush() 49 50 log.Info("Disconnected existing server", "server", server) 51 w.networkStats() 52 return 53 } 54 // If the user requested connecting a new server, do it 55 if w.makeServer() != "" { 56 w.networkStats() 57 } 58 } 59 60 // makeServer reads a single line from stdin and interprets it as a hostname to 61 // connect to. It tries to establish a new SSH session and also executing some 62 // baseline validations. 63 // 64 // If connection succeeds, the server is added to the wizards configs! 65 func (w *wizard) makeServer() string { 66 fmt.Println() 67 fmt.Println("Please enter remote server's address:") 68 69 // Read and dial the server to ensure docker is present 70 input := w.readString() 71 72 client, err := dial(input, nil) 73 if err != nil { 74 log.Error("Server not ready for puppeth", "err", err) 75 return "" 76 } 77 // All checks passed, start tracking the server 78 w.servers[input] = client 79 w.conf.Servers[input] = client.pubkey 80 w.conf.flush() 81 82 return input 83 } 84 85 // selectServer lists the user all the currnetly known servers to choose from, 86 // also granting the option to add a new one. 87 func (w *wizard) selectServer() string { 88 // List the available server to the user and wait for a choice 89 fmt.Println() 90 fmt.Println("Which server do you want to interact with?") 91 92 servers := w.conf.servers() 93 for i, server := range servers { 94 fmt.Printf(" %d. %s\n", i+1, server) 95 } 96 fmt.Printf(" %d. Connect another server\n", len(w.conf.Servers)+1) 97 98 choice := w.readInt() 99 if choice < 0 || choice > len(w.conf.Servers)+1 { 100 log.Error("Invalid server choice, aborting") 101 return "" 102 } 103 // If the user requested connecting to a new server, go for it 104 if choice <= len(w.conf.Servers) { 105 return servers[choice-1] 106 } 107 return w.makeServer() 108 } 109 110 // manageComponents displays a list of network components the user can tear down 111 // and an option 112 func (w *wizard) manageComponents() { 113 // List all the componens we can tear down, along with an entry to deploy a new one 114 fmt.Println() 115 116 var serviceHosts, serviceNames []string 117 for server, services := range w.services { 118 for _, service := range services { 119 serviceHosts = append(serviceHosts, server) 120 serviceNames = append(serviceNames, service) 121 122 fmt.Printf(" %d. Tear down %s on %s\n", len(serviceHosts), strings.Title(service), server) 123 } 124 } 125 fmt.Printf(" %d. Deploy new network component\n", len(serviceHosts)+1) 126 127 choice := w.readInt() 128 if choice < 0 || choice > len(serviceHosts)+1 { 129 log.Error("Invalid component choice, aborting") 130 return 131 } 132 // If the user selected an existing service, destroy it 133 if choice <= len(serviceHosts) { 134 // Figure out the service to destroy and execute it 135 service := serviceNames[choice-1] 136 server := serviceHosts[choice-1] 137 client := w.servers[server] 138 139 if out, err := tearDown(client, w.network, service, true); err != nil { 140 log.Error("Failed to tear down component", "err", err) 141 if len(out) > 0 { 142 fmt.Printf("%s\n", out) 143 } 144 return 145 } 146 // Clean up any references to it from out state 147 services := w.services[server] 148 for i, name := range services { 149 if name == service { 150 w.services[server] = append(services[:i], services[i+1:]...) 151 if len(w.services[server]) == 0 { 152 delete(w.services, server) 153 } 154 } 155 } 156 log.Info("Torn down existing component", "server", server, "service", service) 157 return 158 } 159 // If the user requested deploying a new component, do it 160 w.deployComponent() 161 } 162 163 // deployComponent displays a list of network components the user can deploy and 164 // guides through the process. 165 func (w *wizard) deployComponent() { 166 // Print all the things we can deploy and wait or user choice 167 fmt.Println() 168 fmt.Println("What would you like to deploy? (recommended order)") 169 fmt.Println(" 1. Ethstats - Network monitoring tool") 170 fmt.Println(" 2. Bootnode - Entry point of the network") 171 fmt.Println(" 3. Sealer - Full node minting new blocks") 172 fmt.Println(" 4. Explorer - Chain analysis webservice (ethash only)") 173 fmt.Println(" 5. Wallet - Browser wallet for quick sends") 174 fmt.Println(" 6. Faucet - Crypto faucet to give away funds") 175 fmt.Println(" 7. Dashboard - Website listing above web-services") 176 177 switch w.read() { 178 case "1": 179 w.deployEthstats() 180 case "2": 181 w.deployNode(true) 182 case "3": 183 w.deployNode(false) 184 case "4": 185 w.deployExplorer() 186 case "5": 187 w.deployWallet() 188 case "6": 189 w.deployFaucet() 190 case "7": 191 w.deployDashboard() 192 default: 193 log.Error("That's not something I can do") 194 } 195 }