github.com/axw/juju@v0.0.0-20161005053422-4bd6544d08d4/cmd/juju/cloud/add.go (about) 1 // Copyright 2016 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package cloud 5 6 import ( 7 "github.com/juju/cmd" 8 "github.com/juju/errors" 9 "github.com/juju/gnuflag" 10 11 "github.com/juju/juju/cloud" 12 "github.com/juju/juju/cmd/juju/common" 13 ) 14 15 var usageAddCloudSummary = ` 16 Adds a user-defined cloud to Juju from among known cloud types.`[1:] 17 18 var usageAddCloudDetails = ` 19 A cloud definition file has the following YAML format: 20 21 clouds: 22 mycloud: 23 type: openstack 24 auth-types: [ userpass ] 25 regions: 26 london: 27 endpoint: https://london.mycloud.com:35574/v3.0/ 28 29 If the named cloud already exists, the `[1:] + "`--replace`" + ` option is required to 30 overwrite its configuration. 31 Known cloud types: azure, cloudsigma, ec2, gce, joyent, lxd, maas, manual, 32 openstack, rackspace 33 34 Examples: 35 juju add-cloud mycloud ~/mycloud.yaml 36 37 See also: 38 clouds` 39 40 type addCloudCommand struct { 41 cmd.CommandBase 42 43 // Replace, if true, existing cloud information is overwritten. 44 Replace bool 45 46 // Cloud is the name fo the cloud to add. 47 Cloud string 48 49 // CloudFile is the name of the cloud YAML file. 50 CloudFile string 51 } 52 53 // NewAddCloudCommand returns a command to add cloud information. 54 func NewAddCloudCommand() cmd.Command { 55 return &addCloudCommand{} 56 } 57 58 func (c *addCloudCommand) Info() *cmd.Info { 59 return &cmd.Info{ 60 Name: "add-cloud", 61 Args: "<cloud name> <cloud definition file>", 62 Purpose: usageAddCloudSummary, 63 Doc: usageAddCloudDetails, 64 } 65 } 66 67 func (c *addCloudCommand) SetFlags(f *gnuflag.FlagSet) { 68 c.CommandBase.SetFlags(f) 69 f.BoolVar(&c.Replace, "replace", false, "Overwrite any existing cloud information") 70 } 71 72 func (c *addCloudCommand) Init(args []string) (err error) { 73 if len(args) < 2 { 74 return errors.New("Usage: juju add-cloud <cloud name> <cloud definition file>") 75 } 76 c.Cloud = args[0] 77 c.CloudFile = args[1] 78 return cmd.CheckEmpty(args[2:]) 79 } 80 81 func (c *addCloudCommand) Run(ctxt *cmd.Context) error { 82 specifiedClouds, err := cloud.ParseCloudMetadataFile(c.CloudFile) 83 if err != nil { 84 return err 85 } 86 if specifiedClouds == nil { 87 return errors.New("no personal clouds are defined") 88 } 89 newCloud, ok := specifiedClouds[c.Cloud] 90 if !ok { 91 return errors.Errorf("cloud %q not found in file %q", c.Cloud, c.CloudFile) 92 } 93 publicClouds, _, err := cloud.PublicCloudMetadata() 94 if err != nil { 95 return err 96 } 97 if _, ok = publicClouds[c.Cloud]; ok && !c.Replace { 98 return errors.Errorf("%q is the name of a public cloud; use --replace to use your cloud definition instead", c.Cloud) 99 } 100 builtinClouds := common.BuiltInClouds() 101 if _, ok = builtinClouds[c.Cloud]; ok && !c.Replace { 102 return errors.Errorf("%q is the name of a built-in cloud; use --replace to use your cloud definition instead", c.Cloud) 103 } 104 personalClouds, err := cloud.PersonalCloudMetadata() 105 if err != nil { 106 return err 107 } 108 if _, ok = personalClouds[c.Cloud]; ok && !c.Replace { 109 return errors.Errorf("%q already exists; use --replace to replace this existing cloud", c.Cloud) 110 } 111 if personalClouds == nil { 112 personalClouds = make(map[string]cloud.Cloud) 113 } 114 personalClouds[c.Cloud] = newCloud 115 return cloud.WritePersonalCloudMetadata(personalClouds) 116 }