func providerConfigure(d *schema.ResourceData) (interface{}, error) { remote := d.Get("remote").(string) scheme := d.Get("scheme").(string) daemon_addr := "" switch scheme { case "unix": daemon_addr = fmt.Sprintf("unix:%s", d.Get("address")) case "https": daemon_addr = fmt.Sprintf("https://%s:%s", d.Get("address"), d.Get("port")) default: err := fmt.Errorf("Invalid scheme: %s", scheme) return nil, err } // build LXD config config := lxd.Config{ ConfigDir: os.ExpandEnv("$HOME/.config/lxc"), Remotes: make(map[string]lxd.RemoteConfig), } config.Remotes[remote] = lxd.RemoteConfig{Addr: daemon_addr} log.Printf("[DEBUG] LXD Config: %#v", config) if scheme == "https" { // validate certifictes exist certf := config.ConfigPath("client.crt") keyf := config.ConfigPath("client.key") if !shared.PathExists(certf) || !shared.PathExists(keyf) { err := fmt.Errorf("Certificate or key not found:\n\t%s\n\t%s", certf, keyf) return nil, err } serverCertf := config.ServerCertPath(remote) if !shared.PathExists(serverCertf) { err := fmt.Errorf("Server certificate not found:\n\t%s", serverCertf) return nil, err } } client, err := lxd.NewClient(&config, remote) if err != nil { err := fmt.Errorf("Could not create LXD client: %s", err) return nil, err } log.Printf("[DEBUG] LXD Client: %#v", client) if err := validateClient(client); err != nil { return nil, err } lxdProv := LxdProvider{ Remote: remote, Client: client, } return &lxdProv, nil }
func generateClientCertificate(config *lxd.Config) error { // Generate a client certificate if necessary. The default repositories are // either local or public, neither of which requires a client certificate. // Generation of the cert is delayed to avoid unnecessary overhead, e.g in // testing scenarios where only the default repositories are used. certf := config.ConfigPath("client.crt") keyf := config.ConfigPath("client.key") if !shared.PathExists(certf) || !shared.PathExists(keyf) { fmt.Fprintf(os.Stderr, i18n.G("Generating a client certificate. This may take a minute...")+"\n") return shared.FindOrGenCert(certf, keyf, true) } return nil }
func (c *remoteCmd) run(config *lxd.Config, args []string) error { if len(args) < 1 { return errArgs } switch args[0] { case "add": if len(args) < 3 { return errArgs } if rc, ok := config.Remotes[args[1]]; ok { return fmt.Errorf(i18n.G("remote %s exists as <%s>"), args[1], rc.Addr) } err := c.addServer(config, args[1], args[2], c.acceptCert, c.password, c.public, c.protocol) if err != nil { delete(config.Remotes, args[1]) c.removeCertificate(config, args[1]) return err } case "remove": if len(args) != 2 { return errArgs } rc, ok := config.Remotes[args[1]] if !ok { return fmt.Errorf(i18n.G("remote %s doesn't exist"), args[1]) } if rc.Static { return fmt.Errorf(i18n.G("remote %s is static and cannot be modified"), args[1]) } if config.DefaultRemote == args[1] { return fmt.Errorf(i18n.G("can't remove the default remote")) } delete(config.Remotes, args[1]) c.removeCertificate(config, args[1]) case "list": data := [][]string{} for name, rc := range config.Remotes { strPublic := i18n.G("NO") if rc.Public { strPublic = i18n.G("YES") } strStatic := i18n.G("NO") if rc.Static { strStatic = i18n.G("YES") } if rc.Protocol == "" { rc.Protocol = "lxd" } strName := name if name == config.DefaultRemote { strName = fmt.Sprintf("%s (%s)", name, i18n.G("default")) } data = append(data, []string{strName, rc.Addr, rc.Protocol, strPublic, strStatic}) } table := tablewriter.NewWriter(os.Stdout) table.SetAutoWrapText(false) table.SetAlignment(tablewriter.ALIGN_LEFT) table.SetRowLine(true) table.SetHeader([]string{ i18n.G("NAME"), i18n.G("URL"), i18n.G("PROTOCOL"), i18n.G("PUBLIC"), i18n.G("STATIC")}) sort.Sort(byName(data)) table.AppendBulk(data) table.Render() return nil case "rename": if len(args) != 3 { return errArgs } rc, ok := config.Remotes[args[1]] if !ok { return fmt.Errorf(i18n.G("remote %s doesn't exist"), args[1]) } if rc.Static { return fmt.Errorf(i18n.G("remote %s is static and cannot be modified"), args[1]) } if _, ok := config.Remotes[args[2]]; ok { return fmt.Errorf(i18n.G("remote %s already exists"), args[2]) } // Rename the certificate file oldPath := filepath.Join(config.ConfigPath("servercerts"), fmt.Sprintf("%s.crt", args[1])) newPath := filepath.Join(config.ConfigPath("servercerts"), fmt.Sprintf("%s.crt", args[2])) if shared.PathExists(oldPath) { err := os.Rename(oldPath, newPath) if err != nil { return err } } config.Remotes[args[2]] = rc delete(config.Remotes, args[1]) if config.DefaultRemote == args[1] { config.DefaultRemote = args[2] } case "set-url": if len(args) != 3 { return errArgs } rc, ok := config.Remotes[args[1]] if !ok { return fmt.Errorf(i18n.G("remote %s doesn't exist"), args[1]) } if rc.Static { return fmt.Errorf(i18n.G("remote %s is static and cannot be modified"), args[1]) } config.Remotes[args[1]] = lxd.RemoteConfig{Addr: args[2]} case "set-default": if len(args) != 2 { return errArgs } _, ok := config.Remotes[args[1]] if !ok { return fmt.Errorf(i18n.G("remote %s doesn't exist"), args[1]) } config.DefaultRemote = args[1] case "get-default": if len(args) != 1 { return errArgs } fmt.Println(config.DefaultRemote) return nil default: return errArgs } return lxd.SaveConfig(config, configPath) }
func run() error { verbose := gnuflag.Bool("verbose", false, i18n.G("Enables verbose mode.")) debug := gnuflag.Bool("debug", false, i18n.G("Enables debug mode.")) forceLocal := gnuflag.Bool("force-local", false, i18n.G("Force using the local unix socket.")) noAlias := gnuflag.Bool("no-alias", false, i18n.G("Ignore aliases when determining what command to run.")) configDir := "$HOME/.config/lxc" if os.Getenv("LXD_CONF") != "" { configDir = os.Getenv("LXD_CONF") } configPath = os.ExpandEnv(path.Join(configDir, "config.yml")) if len(os.Args) >= 3 && os.Args[1] == "config" && os.Args[2] == "profile" { fmt.Fprintf(os.Stderr, i18n.G("`lxc config profile` is deprecated, please use `lxc profile`")+"\n") os.Args = append(os.Args[:1], os.Args[2:]...) } if len(os.Args) >= 2 && (os.Args[1] == "-h" || os.Args[1] == "--help") { os.Args[1] = "help" } if len(os.Args) >= 2 && (os.Args[1] == "--all") { os.Args[1] = "help" os.Args = append(os.Args, "--all") } if len(os.Args) == 2 && os.Args[1] == "--version" { os.Args[1] = "version" } if len(os.Args) < 2 { commands["help"].run(nil, nil) os.Exit(1) } var config *lxd.Config var err error if *forceLocal { config = &lxd.DefaultConfig } else { config, err = lxd.LoadConfig(configPath) if err != nil { return err } } // This is quite impolite, but it seems gnuflag needs us to shift our // own exename out of the arguments before parsing them. However, this // is useful for execIfAlias, which wants to know exactly the command // line we received, and in some cases is called before this shift, and // in others after. So, let's save the original args. origArgs := os.Args name := os.Args[1] /* at this point we haven't parsed the args, so we have to look for * --no-alias by hand. */ if !shared.StringInSlice("--no-alias", origArgs) { execIfAliases(config, origArgs) } cmd, ok := commands[name] if !ok { commands["help"].run(nil, nil) fmt.Fprintf(os.Stderr, "\n"+i18n.G("error: unknown command: %s")+"\n", name) os.Exit(1) } cmd.flags() gnuflag.Usage = func() { fmt.Fprintf(os.Stderr, i18n.G("Usage: %s")+"\n\n"+i18n.G("Options:")+"\n\n", strings.TrimSpace(cmd.usage())) gnuflag.PrintDefaults() } os.Args = os.Args[1:] gnuflag.Parse(true) shared.Log, err = logging.GetLogger("", "", *verbose, *debug, nil) if err != nil { return err } certf := config.ConfigPath("client.crt") keyf := config.ConfigPath("client.key") if !*forceLocal && os.Args[0] != "help" && os.Args[0] != "version" && (!shared.PathExists(certf) || !shared.PathExists(keyf)) { fmt.Fprintf(os.Stderr, i18n.G("Generating a client certificate. This may take a minute...")+"\n") err = shared.FindOrGenCert(certf, keyf) if err != nil { return err } } err = cmd.run(config, gnuflag.Args()) if err == errArgs { /* If we got an error about invalid arguments, let's try to * expand this as an alias */ if !*noAlias { execIfAliases(config, origArgs) } fmt.Fprintf(os.Stderr, "%s\n\n"+i18n.G("error: %v")+"\n", cmd.usage(), err) os.Exit(1) } return err }