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  }