github.com/Pankov404/juju@v0.0.0-20150703034450-be266991dceb/cmd/juju/storage/storage.go (about) 1 // Copyright 2015 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package storage 5 6 import ( 7 "github.com/juju/cmd" 8 "github.com/juju/errors" 9 "github.com/juju/loggo" 10 "github.com/juju/names" 11 12 "github.com/juju/juju/api/storage" 13 "github.com/juju/juju/apiserver/params" 14 "github.com/juju/juju/cmd/envcmd" 15 ) 16 17 var logger = loggo.GetLogger("juju.cmd.juju.storage") 18 19 const storageCmdDoc = ` 20 "juju storage" is used to manage storage instances in 21 the Juju environment. 22 ` 23 24 const storageCmdPurpose = "manage storage instances" 25 26 // Command is the top-level command wrapping all storage functionality. 27 type Command struct { 28 cmd.SuperCommand 29 } 30 31 // NewSuperCommand creates the storage supercommand and 32 // registers the subcommands that it supports. 33 func NewSuperCommand() cmd.Command { 34 storagecmd := Command{ 35 SuperCommand: *cmd.NewSuperCommand( 36 cmd.SuperCommandParams{ 37 Name: "storage", 38 Doc: storageCmdDoc, 39 UsagePrefix: "juju", 40 Purpose: storageCmdPurpose, 41 })} 42 storagecmd.Register(envcmd.Wrap(&ShowCommand{})) 43 storagecmd.Register(envcmd.Wrap(&ListCommand{})) 44 storagecmd.Register(envcmd.Wrap(&AddCommand{})) 45 storagecmd.Register(NewPoolSuperCommand()) 46 storagecmd.Register(NewVolumeSuperCommand()) 47 return &storagecmd 48 } 49 50 // StorageCommandBase is a helper base structure that has a method to get the 51 // storage managing client. 52 type StorageCommandBase struct { 53 envcmd.EnvCommandBase 54 } 55 56 // NewStorageAPI returns a storage api for the root api endpoint 57 // that the environment command returns. 58 func (c *StorageCommandBase) NewStorageAPI() (*storage.Client, error) { 59 root, err := c.NewAPIRoot() 60 if err != nil { 61 return nil, err 62 } 63 return storage.NewClient(root), nil 64 } 65 66 // StorageInfo defines the serialization behaviour of the storage information. 67 type StorageInfo struct { 68 StorageName string `yaml:"storage" json:"storage"` 69 Kind string `yaml:"kind" json:"kind"` 70 Status string `yaml:"status,omitempty" json:"status,omitempty"` 71 Persistent bool `yaml:"persistent" json:"persistent"` 72 Location string `yaml:"location,omitempty" json:"location,omitempty"` 73 } 74 75 // formatStorageDetails takes a set of StorageDetail and creates a 76 // mapping keyed on unit and storage id. 77 func formatStorageDetails(storages []params.StorageDetails) (map[string]map[string]StorageInfo, error) { 78 if len(storages) == 0 { 79 return nil, nil 80 } 81 output := make(map[string]map[string]StorageInfo) 82 for _, one := range storages { 83 storageTag, err := names.ParseStorageTag(one.StorageTag) 84 if err != nil { 85 return nil, errors.Annotate(err, "invalid storage tag") 86 } 87 unitTag, err := names.ParseTag(one.UnitTag) 88 if err != nil { 89 return nil, errors.Annotate(err, "invalid unit tag") 90 } 91 92 storageName, err := names.StorageName(storageTag.Id()) 93 if err != nil { 94 panic(err) // impossible 95 } 96 si := StorageInfo{ 97 StorageName: storageName, 98 Kind: one.Kind.String(), 99 Status: one.Status, 100 Location: one.Location, 101 Persistent: one.Persistent, 102 } 103 unit := unitTag.Id() 104 unitColl, ok := output[unit] 105 if !ok { 106 unitColl = map[string]StorageInfo{} 107 output[unit] = unitColl 108 } 109 unitColl[storageTag.Id()] = si 110 } 111 return output, nil 112 }