jkawamoto/roadie

View on GitHub
command/init.go

Summary

Maintainability
A
1 hr
Test Coverage
//
// command/init.go
//
// Copyright (c) 2016-2017 Junpei Kawamoto
//
// This file is part of Roadie.
//
// Roadie is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Roadie is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Roadie.  If not, see <http://www.gnu.org/licenses/>.
//

package command

import (
    "fmt"
    "strings"

    "github.com/jkawamoto/roadie/config"
    "github.com/ttacon/chalk"

    "github.com/deiwin/interact"
    "github.com/urfave/cli"
)

// CmdInit helps to create a configuration file.
func CmdInit(c *cli.Context) (err error) {

    // If metadata don't have complete information, it's okay for now.
    m, _ := getMetadata(c)

    err = cmdInit(m)
    if err != nil {
        return cli.NewExitError(err, 2)
    }
    return

}

// cmdInit initialize Roadie.
// The initialization steps:
// 1. Choose cloud service provider (GCP only).
// 2. Ask nessesarry information (project id for gcp).
// 3. Authentication.
// 4. Store configurations.
func cmdInit(m *Metadata) (err error) {

    if m.Config == nil {
        m.Config = new(config.Config)
    }
    if m.Config.FileName == "" {
        m.Config.FileName = ConfigFile
    }

    fmt.Fprintf(m.Stdout, `%v
This command will create file %q in current directory.
Configurations can be updated with "roadie config" command.
See "roadie config --help", for more detail.

`, chalk.Green.Color("Initialize Roadie"), m.Config.FileName)

    actor := interact.NewActor(m.Stdin, m.Stdout)

    provider, err := actor.PromptOptionalAndRetry("Choose a cloud provider from a) Microsoft Azure, g) Google Cloud Platform", "g", checkOption("a", "g"))
    if err != nil {
        return
    }
    switch provider {
    case "a":
        var tennant, subscription, project string
        tennant, err = actor.PromptAndRetry("Enter your tennant ID", checkNotEmpty)
        if err != nil {
            return
        }
        fmt.Fprintln(m.Stdout, "")
        m.Config.AzureConfig.TenantID = tennant

        subscription, err = actor.PromptAndRetry("Enter your subscription ID", checkNotEmpty)
        if err != nil {
            return
        }
        fmt.Fprintln(m.Stdout, "")
        m.Config.AzureConfig.SubscriptionID = subscription

        project, err = actor.PromptAndRetry("Enter your project ID", checkNotEmpty)
        if err != nil {
            return
        }
        fmt.Fprintln(m.Stdout, "")
        m.Config.AzureConfig.ProjectID = project

    case "g":
        var project string
        project, err = actor.PromptAndRetry("Enter your project ID", checkNotEmpty)
        if err != nil {
            return
        }
        fmt.Fprintln(m.Stdout, "")
        m.Config.GcpConfig.Project = project

    }

    fmt.Fprintln(m.Stdout, chalk.Green.Color("Cheking authorization..."))
    err = m.prepareProvider(true)
    if err != nil {
        return
    }

    fmt.Fprintln(m.Stdout, chalk.Green.Color("Saving configuarions..."))
    return m.Config.Save()

}

// checkNotEmpty is a predicate used in actor to check input message is empty.
func checkNotEmpty(value string) error {
    if value == "" {
        return fmt.Errorf("Input value is empty.")
    }
    return nil
}

// checkOption returns InputCheck checks a given string matches at least one of
// given options.
func checkOption(options ...string) interact.InputCheck {
    return func(str string) error {
        for _, v := range options {
            if v == str {
                return nil
            }
        }
        return fmt.Errorf("Input must be one of [%v]", strings.Join(options, ", "))
    }
}