github.com/emc-advanced-dev/unik@v0.0.0-20190717152701-a58d3e8e33b7/cmd/configure.go (about) 1 package cmd 2 3 import ( 4 "bufio" 5 "fmt" 6 "os" 7 8 "github.com/sirupsen/logrus" 9 "github.com/emc-advanced-dev/pkg/errors" 10 "github.com/solo-io/unik/pkg/config" 11 "github.com/spf13/cobra" 12 "gopkg.in/yaml.v2" 13 "io/ioutil" 14 "path/filepath" 15 "strings" 16 ) 17 18 var configureCmd = &cobra.Command{ 19 Use: "configure [--provider PROVIDER-NAME]", 20 Short: "A generate configuration file for daemon ('daemon.yaml')", 21 Long: `An interactive command to help walk you through the process of creating or changing a configuration file for unik. 22 Can be used to configure an individual provider, or any number of providers. 23 24 Usage: 25 unik configure # will iterate through all possible providers and ask if user wants to configure 26 -or- 27 unik configure --provider PROVIDER 28 where provider is one of the following: 29 aws 30 gcloud 31 openstack 32 qemu 33 ukvm 34 virtualbox 35 vsphere 36 xen 37 38 `, 39 Run: func(cmd *cobra.Command, args []string) { 40 if daemonConfigFile == "" { 41 daemonConfigFile = os.Getenv("HOME")+"/.unik/daemon-config.yaml" 42 } 43 readDaemonConfig() 44 reader := bufio.NewReader(os.Stdin) 45 var configFunc func() error 46 switch strings.ToLower(provider) { 47 case "aws": 48 configFunc = func() error { 49 if err := doAwsConfig(reader); err != nil { 50 return err 51 } 52 return nil 53 } 54 case "gcloud": 55 configFunc = func() error { 56 if err := doGcloudConfig(reader); err != nil { 57 return err 58 } 59 return nil 60 } 61 case "openstack": 62 configFunc = func() error { 63 if err := doOpenstackConfig(reader); err != nil { 64 return err 65 } 66 return nil 67 } 68 case "qemu": 69 configFunc = func() error { 70 if err := doQemuConfig(reader); err != nil { 71 return err 72 } 73 return nil 74 } 75 case "ukvm": 76 configFunc = func() error { 77 if err := doUkvmConfig(reader); err != nil { 78 return err 79 } 80 return nil 81 } 82 case "virtualbox": 83 configFunc = func() error { 84 if err := doVirtualboxConfig(reader); err != nil { 85 return err 86 } 87 return nil 88 } 89 case "vsphere": 90 configFunc = func() error { 91 if err := doVsphereConfig(reader); err != nil { 92 return err 93 } 94 return nil 95 } 96 case "xen": 97 configFunc = func() error { 98 if err := doXenConfig(reader); err != nil { 99 return err 100 } 101 return nil 102 } 103 case "": 104 configFunc = func() error { 105 if err := doAwsConfig(reader); err != nil { 106 return err 107 } 108 if err := doGcloudConfig(reader); err != nil { 109 return err 110 } 111 if err := doOpenstackConfig(reader); err != nil { 112 return err 113 } 114 if err := doQemuConfig(reader); err != nil { 115 return err 116 } 117 if err := doUkvmConfig(reader); err != nil { 118 return err 119 } 120 if err := doVirtualboxConfig(reader); err != nil { 121 return err 122 } 123 if err := doVsphereConfig(reader); err != nil { 124 return err 125 } 126 if err := doXenConfig(reader); err != nil { 127 return err 128 } 129 return nil 130 } 131 } 132 if err := configFunc(); err != nil { 133 logrus.Fatal(err) 134 } 135 if err := writeDaemonConfig(); err != nil { 136 logrus.Fatal(err) 137 } 138 139 }, 140 } 141 142 func init() { 143 RootCmd.AddCommand(configureCmd) 144 configureCmd.Flags().StringVar(&provider, "provider", "", "<string,optional> provider to configure. if not given, unik will iterate through each possible provider to configure") 145 configureCmd.Flags().StringVar(&daemonConfigFile, "f", os.Getenv("HOME")+"/.unik/daemon-config.yaml", "<string, optional> output path for daemon config file") 146 } 147 148 func writeDaemonConfig() error { 149 data, err := yaml.Marshal(daemonConfig) 150 if err != nil { 151 return errors.New("failed to convert config to yaml string ", err) 152 } 153 os.MkdirAll(filepath.Dir(daemonConfigFile), 0755) 154 if err := ioutil.WriteFile(daemonConfigFile, data, 0644); err != nil { 155 return errors.New("failed writing config to file "+daemonConfigFile, err) 156 } 157 return nil 158 } 159 160 func doAwsConfig(reader *bufio.Reader) error { 161 fmt.Print("Do you wish to configure unik for use with AWS? [y/N]: ") 162 y, err := reader.ReadString('\n') 163 if err != nil { 164 return err 165 } 166 y = strings.TrimSuffix(y, "\n") 167 if y == "y" { 168 if len(daemonConfig.Providers.Aws) < 1 { 169 daemonConfig.Providers.Aws = append(daemonConfig.Providers.Aws, config.Aws{}) 170 } 171 if daemonConfig.Providers.Aws[0].Name == "" { 172 daemonConfig.Providers.Aws[0].Name = "aws-configuration" 173 } 174 fmt.Printf("AWS region where to deploy unikernels [%s]: ", daemonConfig.Providers.Aws[0].Region) 175 region, err := reader.ReadString('\n') 176 if err != nil { 177 return err 178 } 179 region = strings.TrimSuffix(region, "\n") 180 if region != "" { 181 daemonConfig.Providers.Aws[0].Region = region 182 } 183 fmt.Printf("AWS availability zone where to deploy unikernels (must be within region) [%s]: ", daemonConfig.Providers.Aws[0].Zone) 184 zone, err := reader.ReadString('\n') 185 if err != nil { 186 return err 187 } 188 zone = strings.TrimSuffix(zone, "\n") 189 if zone != "" { 190 daemonConfig.Providers.Aws[0].Zone = zone 191 } 192 } 193 return nil 194 } 195 196 func doGcloudConfig(reader *bufio.Reader) error { 197 fmt.Print("Do you wish to configure unik for use with Google Compute Engine? [y/N]: ") 198 y, err := reader.ReadString('\n') 199 if err != nil { 200 return err 201 } 202 y = strings.TrimSuffix(y, "\n") 203 if y == "y" { 204 if len(daemonConfig.Providers.Gcloud) < 1 { 205 daemonConfig.Providers.Gcloud = append(daemonConfig.Providers.Gcloud, config.Gcloud{}) 206 } 207 if daemonConfig.Providers.Gcloud[0].Name == "" { 208 daemonConfig.Providers.Gcloud[0].Name = "gcloud-configuration" 209 } 210 fmt.Printf("GCloud project id under which to deploy unikernels [%s]: ", daemonConfig.Providers.Gcloud[0].ProjectID) 211 projectId, err := reader.ReadString('\n') 212 if err != nil { 213 return err 214 } 215 projectId = strings.TrimSuffix(projectId, "\n") 216 if projectId != "" { 217 daemonConfig.Providers.Gcloud[0].ProjectID = projectId 218 } 219 fmt.Printf("Gcloud availability zone where to deploy unikernels (must be within region) [%s]: ", daemonConfig.Providers.Gcloud[0].Zone) 220 zone, err := reader.ReadString('\n') 221 if err != nil { 222 return err 223 } 224 zone = strings.TrimSuffix(zone, "\n") 225 if zone != "" { 226 daemonConfig.Providers.Gcloud[0].Zone = zone 227 } 228 } 229 return nil 230 } 231 232 func doOpenstackConfig(reader *bufio.Reader) error { 233 fmt.Print("Do you wish to configure unik for use with Openstack? [y/N]: ") 234 y, err := reader.ReadString('\n') 235 if err != nil { 236 return err 237 } 238 y = strings.TrimSuffix(y, "\n") 239 if y == "y" { 240 if len(daemonConfig.Providers.Openstack) < 1 { 241 daemonConfig.Providers.Openstack = append(daemonConfig.Providers.Openstack, config.Openstack{}) 242 } 243 if daemonConfig.Providers.Openstack[0].Name == "" { 244 daemonConfig.Providers.Openstack[0].Name = "Openstack-configuration" 245 } 246 fmt.Printf("Openstack username for authentication [%s]: ", daemonConfig.Providers.Openstack[0].UserName) 247 username, err := reader.ReadString('\n') 248 if err != nil { 249 return err 250 } 251 username = strings.TrimSuffix(username, "\n") 252 if username != "" { 253 daemonConfig.Providers.Openstack[0].UserName = username 254 } 255 fmt.Printf("Openstack password for authentication [%s]: ", daemonConfig.Providers.Openstack[0].Password) 256 password, err := reader.ReadString('\n') 257 if err != nil { 258 return err 259 } 260 password = strings.TrimSuffix(password, "\n") 261 if password != "" { 262 daemonConfig.Providers.Openstack[0].Password = password 263 } 264 fmt.Printf("Openstack authentication url [%s]: ", daemonConfig.Providers.Openstack[0].AuthUrl) 265 authUrl, err := reader.ReadString('\n') 266 if err != nil { 267 return err 268 } 269 authUrl = strings.TrimSuffix(authUrl, "\n") 270 if authUrl != "" { 271 daemonConfig.Providers.Openstack[0].AuthUrl = authUrl 272 } 273 fmt.Printf("Openstack tenant id [%s]: ", daemonConfig.Providers.Openstack[0].TenantId) 274 tenantId, err := reader.ReadString('\n') 275 if err != nil { 276 return err 277 } 278 tenantId = strings.TrimSuffix(tenantId, "\n") 279 if tenantId != "" { 280 daemonConfig.Providers.Openstack[0].TenantId = tenantId 281 } 282 fmt.Printf("Openstack project name [%s]: ", daemonConfig.Providers.Openstack[0].ProjectName) 283 projectName, err := reader.ReadString('\n') 284 if err != nil { 285 return err 286 } 287 projectName = strings.TrimSuffix(projectName, "\n") 288 if projectName != "" { 289 daemonConfig.Providers.Openstack[0].ProjectName = projectName 290 } 291 fmt.Printf("Openstack region id [%s]: ", daemonConfig.Providers.Openstack[0].RegionId) 292 regionId, err := reader.ReadString('\n') 293 if err != nil { 294 return err 295 } 296 regionId = strings.TrimSuffix(regionId, "\n") 297 if regionId != "" { 298 daemonConfig.Providers.Openstack[0].RegionId = regionId 299 } 300 fmt.Printf("Openstack network uuid [%s]: ", daemonConfig.Providers.Openstack[0].NetworkUUID) 301 networkUUID, err := reader.ReadString('\n') 302 if err != nil { 303 return err 304 } 305 networkUUID = strings.TrimSuffix(networkUUID, "\n") 306 if networkUUID != "" { 307 daemonConfig.Providers.Openstack[0].NetworkUUID = networkUUID 308 } 309 } 310 return nil 311 } 312 313 func doQemuConfig(reader *bufio.Reader) error { 314 fmt.Print("Do you wish to configure unik for use with Qemu? [y/N]: ") 315 y, err := reader.ReadString('\n') 316 if err != nil { 317 return err 318 } 319 y = strings.TrimSuffix(y, "\n") 320 if y == "y" { 321 if len(daemonConfig.Providers.Qemu) < 1 { 322 daemonConfig.Providers.Qemu = append(daemonConfig.Providers.Qemu, config.Qemu{}) 323 } 324 if daemonConfig.Providers.Qemu[0].Name == "" { 325 daemonConfig.Providers.Qemu[0].Name = "Qemu-configuration" 326 } 327 fmt.Print("Run Qemu unikernels in nograpic mode [y/N]? (recommended for non-graphical environments): ") 328 nographic, err := reader.ReadString('\n') 329 if err != nil { 330 return err 331 } 332 nographic = strings.TrimSuffix(nographic, "\n") 333 if nographic == "y" { 334 daemonConfig.Providers.Qemu[0].NoGraphic = true 335 } 336 } 337 return nil 338 } 339 340 func doUkvmConfig(reader *bufio.Reader) error { 341 fmt.Print("Do you wish to configure unik for use with Ukvm? [y/N]: ") 342 y, err := reader.ReadString('\n') 343 if err != nil { 344 return err 345 } 346 y = strings.TrimSuffix(y, "\n") 347 if y == "y" { 348 if len(daemonConfig.Providers.Ukvm) < 1 { 349 daemonConfig.Providers.Ukvm = append(daemonConfig.Providers.Ukvm, config.Ukvm{}) 350 } 351 if daemonConfig.Providers.Ukvm[0].Name == "" { 352 daemonConfig.Providers.Ukvm[0].Name = "Ukvm-configuration" 353 } 354 fmt.Printf("Name of tap device to attach to Ukvm unikernels [%s]: ", daemonConfig.Providers.Ukvm[0].Tap) 355 tapDevice, err := reader.ReadString('\n') 356 if err != nil { 357 return err 358 } 359 tapDevice = strings.TrimSuffix(tapDevice, "\n") 360 if tapDevice != "" { 361 daemonConfig.Providers.Ukvm[0].Tap = tapDevice 362 } 363 } 364 return nil 365 } 366 367 func doVirtualboxConfig(reader *bufio.Reader) error { 368 fmt.Print("Do you wish to configure unik for use with Virtualbox? [y/N]: ") 369 y, err := reader.ReadString('\n') 370 if err != nil { 371 return err 372 } 373 y = strings.TrimSuffix(y, "\n") 374 if y == "y" { 375 if len(daemonConfig.Providers.Virtualbox) < 1 { 376 daemonConfig.Providers.Virtualbox = append(daemonConfig.Providers.Virtualbox, config.Virtualbox{}) 377 } 378 if daemonConfig.Providers.Virtualbox[0].Name == "" { 379 daemonConfig.Providers.Virtualbox[0].Name = "Virtualbox-configuration" 380 } 381 fmt.Printf("Virtualbox Network Type (bridged or host_only) [%s]: ", daemonConfig.Providers.Virtualbox[0].VirtualboxAdapterType) 382 adapterType, err := reader.ReadString('\n') 383 if err != nil { 384 return err 385 } 386 adapterType = strings.TrimSuffix(adapterType, "\n") 387 if adapterType != "" { 388 daemonConfig.Providers.Virtualbox[0].VirtualboxAdapterType = config.VirtualboxAdapterType(adapterType) 389 } 390 fmt.Printf("Name of network adapter to attach to virtualbox instances [%s]: ", daemonConfig.Providers.Virtualbox[0].AdapterName) 391 adapterName, err := reader.ReadString('\n') 392 if err != nil { 393 return err 394 } 395 adapterName = strings.TrimSuffix(adapterName, "\n") 396 if adapterName != "" { 397 daemonConfig.Providers.Virtualbox[0].AdapterName = adapterName 398 } 399 } 400 return nil 401 } 402 403 func doVsphereConfig(reader *bufio.Reader) error { 404 fmt.Print("Do you wish to configure unik for use with Vsphere? [y/N]: ") 405 y, err := reader.ReadString('\n') 406 if err != nil { 407 return err 408 } 409 y = strings.TrimSuffix(y, "\n") 410 if y == "y" { 411 if len(daemonConfig.Providers.Vsphere) < 1 { 412 daemonConfig.Providers.Vsphere = append(daemonConfig.Providers.Vsphere, config.Vsphere{}) 413 } 414 if daemonConfig.Providers.Vsphere[0].Name == "" { 415 daemonConfig.Providers.Vsphere[0].Name = "Vsphere-configuration" 416 } 417 fmt.Printf("Vsphere username for authentication [%s]: ", daemonConfig.Providers.Vsphere[0].VsphereUser) 418 username, err := reader.ReadString('\n') 419 if err != nil { 420 return err 421 } 422 username = strings.TrimSuffix(username, "\n") 423 if username != "" { 424 daemonConfig.Providers.Vsphere[0].VsphereUser = username 425 } 426 fmt.Printf("Vsphere password for authentication [%s]: ", daemonConfig.Providers.Vsphere[0].VspherePassword) 427 password, err := reader.ReadString('\n') 428 if err != nil { 429 return err 430 } 431 password = strings.TrimSuffix(password, "\n") 432 if password != "" { 433 daemonConfig.Providers.Vsphere[0].VspherePassword = password 434 } 435 fmt.Printf("Vsphere authentication url [%s]: ", daemonConfig.Providers.Vsphere[0].VsphereURL) 436 authUrl, err := reader.ReadString('\n') 437 if err != nil { 438 return err 439 } 440 authUrl = strings.TrimSuffix(authUrl, "\n") 441 if authUrl != "" { 442 daemonConfig.Providers.Vsphere[0].VsphereURL = authUrl 443 } 444 fmt.Printf("Vsphere datastore name [%s]: ", daemonConfig.Providers.Vsphere[0].Datastore) 445 datastore, err := reader.ReadString('\n') 446 if err != nil { 447 return err 448 } 449 datastore = strings.TrimSuffix(datastore, "\n") 450 if datastore != "" { 451 daemonConfig.Providers.Vsphere[0].Datastore = datastore 452 } 453 fmt.Printf("Vsphere datacenter name [%s]: ", daemonConfig.Providers.Vsphere[0].Datacenter) 454 datacenter, err := reader.ReadString('\n') 455 if err != nil { 456 return err 457 } 458 datacenter = strings.TrimSuffix(datacenter, "\n") 459 if datacenter != "" { 460 daemonConfig.Providers.Vsphere[0].Datacenter = datacenter 461 } 462 } 463 return nil 464 } 465 466 func doXenConfig(reader *bufio.Reader) error { 467 fmt.Print("Do you wish to configure unik for use with Xen? [y/N]: ") 468 y, err := reader.ReadString('\n') 469 if err != nil { 470 return err 471 } 472 y = strings.TrimSuffix(y, "\n") 473 if y == "y" { 474 if len(daemonConfig.Providers.Xen) < 1 { 475 daemonConfig.Providers.Xen = append(daemonConfig.Providers.Xen, config.Xen{}) 476 } 477 if daemonConfig.Providers.Xen[0].Name == "" { 478 daemonConfig.Providers.Xen[0].Name = "Xen-configuration" 479 } 480 fmt.Printf("Name of xen bridge network interface to attach to Xen unikernels [%s]: ", daemonConfig.Providers.Xen[0].XenBridge) 481 xenBridge, err := reader.ReadString('\n') 482 if err != nil { 483 return err 484 } 485 xenBridge = strings.TrimSuffix(xenBridge, "\n") 486 if xenBridge != "" { 487 daemonConfig.Providers.Xen[0].XenBridge = xenBridge 488 } 489 fmt.Printf("Path to PV Grub Boot Manager (see https://wiki.xen.org/wiki/PvGrub#Build for more info) [%s]: ", daemonConfig.Providers.Xen[0].KernelPath) 490 pvKernel, err := reader.ReadString('\n') 491 if err != nil { 492 return err 493 } 494 pvKernel = strings.TrimSuffix(pvKernel, "\n") 495 if pvKernel != "" { 496 daemonConfig.Providers.Xen[0].KernelPath = pvKernel 497 } 498 } 499 return nil 500 }