github.com/cloudfoundry-attic/ltc@v0.0.0-20151123212628-098adc7919fc/config/command_factory/config_command_factory.go (about)

     1  package command_factory
     2  
     3  import (
     4  	"fmt"
     5  
     6  	"github.com/cloudfoundry-incubator/ltc/config"
     7  	"github.com/cloudfoundry-incubator/ltc/config/target_verifier"
     8  	"github.com/cloudfoundry-incubator/ltc/exit_handler"
     9  	"github.com/cloudfoundry-incubator/ltc/exit_handler/exit_codes"
    10  	"github.com/cloudfoundry-incubator/ltc/terminal"
    11  	"github.com/cloudfoundry-incubator/ltc/version"
    12  	"github.com/codegangsta/cli"
    13  )
    14  
    15  type ConfigCommandFactory struct {
    16  	config            *config.Config
    17  	ui                terminal.UI
    18  	targetVerifier    target_verifier.TargetVerifier
    19  	blobStoreVerifier BlobStoreVerifier
    20  	exitHandler       exit_handler.ExitHandler
    21  	versionManager    version.VersionManager
    22  }
    23  
    24  //go:generate counterfeiter -o fake_blob_store_verifier/fake_blob_store_verifier.go . BlobStoreVerifier
    25  type BlobStoreVerifier interface {
    26  	Verify(config *config.Config) (authorized bool, err error)
    27  }
    28  
    29  func NewConfigCommandFactory(config *config.Config, ui terminal.UI, targetVerifier target_verifier.TargetVerifier, blobStoreVerifier BlobStoreVerifier, exitHandler exit_handler.ExitHandler, versionManager version.VersionManager) *ConfigCommandFactory {
    30  	return &ConfigCommandFactory{config, ui, targetVerifier, blobStoreVerifier, exitHandler, versionManager}
    31  }
    32  
    33  func (factory *ConfigCommandFactory) MakeTargetCommand() cli.Command {
    34  	var targetFlags = []cli.Flag{
    35  		cli.BoolFlag{
    36  			Name:  "s3",
    37  			Usage: "Target an S3 bucket as the droplet store",
    38  		},
    39  		cli.BoolFlag{
    40  			Name:  "domain, d",
    41  			Usage: "Print the currently targeted lattice deployment's domain name",
    42  		},
    43  	}
    44  
    45  	var targetCommand = cli.Command{
    46  		Name:        "target",
    47  		Aliases:     []string{"ta"},
    48  		Usage:       "Targets a lattice cluster",
    49  		Description: "ltc target <system-domain> (e.g., 192.168.11.11.xip.io)",
    50  		Action:      factory.target,
    51  		Flags:       targetFlags,
    52  	}
    53  
    54  	return targetCommand
    55  }
    56  
    57  func (factory *ConfigCommandFactory) target(context *cli.Context) {
    58  	target := context.Args().First()
    59  	s3Enabled := context.Bool("s3")
    60  	domainOnlyFlag := context.Bool("domain")
    61  
    62  	if target == "" {
    63  		if domainOnlyFlag {
    64  			if factory.config.Target() != "" {
    65  				factory.ui.SayLine(factory.config.Target())
    66  			}
    67  		} else {
    68  			factory.printTarget()
    69  			factory.printBlobTarget()
    70  		}
    71  		return
    72  	}
    73  
    74  	factory.config.SetTarget(target)
    75  	factory.config.SetLogin("", "")
    76  
    77  	if s3Enabled {
    78  		accessKey := factory.ui.Prompt("S3 Access Key")
    79  		secretKey := factory.ui.PromptForPassword("S3 Secret Key")
    80  		bucketName := factory.ui.Prompt("S3 Bucket")
    81  		region := factory.ui.Prompt("S3 Region")
    82  		factory.config.SetS3BlobStore(accessKey, secretKey, bucketName, region)
    83  	} else {
    84  		factory.config.SetBlobStore(target, "8444", "", "")
    85  	}
    86  
    87  	_, authorized, err := factory.targetVerifier.VerifyTarget(factory.config.Receptor())
    88  	if err != nil {
    89  		factory.ui.SayLine(fmt.Sprint("Error verifying target: ", err))
    90  		factory.exitHandler.Exit(exit_codes.BadTarget)
    91  		return
    92  	}
    93  	if authorized {
    94  		if !factory.verifyBlobStore() {
    95  			factory.exitHandler.Exit(exit_codes.BadTarget)
    96  			return
    97  		}
    98  
    99  		factory.checkVersions()
   100  		factory.save()
   101  		return
   102  	}
   103  
   104  	username := factory.ui.Prompt("Username")
   105  	password := factory.ui.PromptForPassword("Password")
   106  
   107  	factory.config.SetLogin(username, password)
   108  	factory.config.SetBlobStore(target, "8444", username, password)
   109  
   110  	_, authorized, err = factory.targetVerifier.VerifyTarget(factory.config.Receptor())
   111  	if err != nil {
   112  		factory.ui.SayLine(fmt.Sprint("Error verifying target: ", err))
   113  		factory.exitHandler.Exit(exit_codes.BadTarget)
   114  		return
   115  	}
   116  	if !authorized {
   117  		factory.ui.SayLine("Could not authorize target.")
   118  		factory.exitHandler.Exit(exit_codes.BadTarget)
   119  		return
   120  	}
   121  
   122  	if !factory.verifyBlobStore() {
   123  		factory.ui.SayLine("Failed to verify blob store")
   124  		factory.exitHandler.Exit(exit_codes.BadTarget)
   125  		return
   126  	}
   127  
   128  	factory.checkVersions()
   129  	factory.save()
   130  }
   131  
   132  func (factory *ConfigCommandFactory) verifyBlobStore() bool {
   133  	authorized, err := factory.blobStoreVerifier.Verify(factory.config)
   134  	if err != nil {
   135  		factory.ui.SayLine("Could not connect to the droplet store.")
   136  		return false
   137  	}
   138  	if !authorized {
   139  		factory.ui.SayLine("Could not authenticate with the droplet store.")
   140  		return false
   141  	}
   142  	return true
   143  }
   144  
   145  func (f *ConfigCommandFactory) checkVersions() {
   146  	ltcMatchesServer, err := f.versionManager.LtcMatchesServer(f.config.Receptor())
   147  	if !ltcMatchesServer {
   148  		f.ui.SayLine(fmt.Sprintf("WARNING: local ltc version (%s) does not match target expected version.", f.versionManager.LatticeVersion()))
   149  
   150  		if err == nil {
   151  			f.ui.SayLine("Run `ltc sync` to replace your local ltc command-line tool with your target cluster's expected version.")
   152  		}
   153  	}
   154  
   155  }
   156  
   157  func (factory *ConfigCommandFactory) save() {
   158  	err := factory.config.Save()
   159  	if err != nil {
   160  		factory.ui.SayLine(err.Error())
   161  		factory.exitHandler.Exit(exit_codes.FileSystemError)
   162  		return
   163  	}
   164  
   165  	factory.ui.SayLine("API location set.")
   166  }
   167  
   168  func (factory *ConfigCommandFactory) printTarget() {
   169  	if factory.config.Target() == "" {
   170  		factory.ui.SayLine("Target not set.")
   171  		return
   172  	}
   173  	target := factory.config.Target()
   174  	if username := factory.config.Username(); username != "" {
   175  		target = fmt.Sprintf("%s@%s", username, target)
   176  	}
   177  	factory.ui.SayLine(fmt.Sprintf("Target:\t\t%s", target))
   178  }
   179  
   180  func (factory *ConfigCommandFactory) printBlobTarget() {
   181  	var endpoint string
   182  	if factory.config.ActiveBlobStore() == config.S3BlobStore {
   183  		endpoint = fmt.Sprintf("s3://%s (%s)", factory.config.S3BlobStore().BucketName, factory.config.S3BlobStore().Region)
   184  	} else {
   185  		blobStore := factory.config.BlobStore()
   186  		if blobStore.Host == "" {
   187  			factory.ui.SayLine("\tNo droplet store specified.")
   188  			return
   189  		}
   190  
   191  		endpoint = fmt.Sprintf("%s:%s", blobStore.Host, blobStore.Port)
   192  		if username := blobStore.Username; username != "" {
   193  			endpoint = fmt.Sprintf("%s@%s", username, endpoint)
   194  		}
   195  	}
   196  
   197  	factory.ui.SayLine(fmt.Sprintf("Droplet store:\t%s", endpoint))
   198  }