github.com/makyo/juju@v0.0.0-20160425123129-2608902037e9/cmd/juju/storage/storage.go (about) 1 // Copyright 2015 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 // The storage command provides a storage management interface, 5 // for manipulating and inspecting storage entities (volumes, 6 // filesystems, charm storage). 7 package storage 8 9 import ( 10 "github.com/juju/errors" 11 "github.com/juju/names" 12 13 "github.com/juju/juju/api/storage" 14 "github.com/juju/juju/apiserver/params" 15 "github.com/juju/juju/cmd/juju/common" 16 "github.com/juju/juju/cmd/modelcmd" 17 ) 18 19 // StorageCommandBase is a helper base structure that has a method to get the 20 // storage managing client. 21 type StorageCommandBase struct { 22 modelcmd.ModelCommandBase 23 } 24 25 // NewStorageAPI returns a storage api for the root api endpoint 26 // that the environment command returns. 27 func (c *StorageCommandBase) NewStorageAPI() (*storage.Client, error) { 28 root, err := c.NewAPIRoot() 29 if err != nil { 30 return nil, err 31 } 32 return storage.NewClient(root), nil 33 } 34 35 // StorageInfo defines the serialization behaviour of the storage information. 36 type StorageInfo struct { 37 Kind string `yaml:"kind" json:"kind"` 38 Status EntityStatus `yaml:"status" json:"status"` 39 Persistent bool `yaml:"persistent" json:"persistent"` 40 Attachments *StorageAttachments `yaml:"attachments" json:"attachments"` 41 } 42 43 // StorageAttachments contains details about all attachments to a storage 44 // instance. 45 type StorageAttachments struct { 46 // Units is a mapping from unit ID to unit storage attachment details. 47 Units map[string]UnitStorageAttachment `yaml:"units" json:"units"` 48 } 49 50 // UnitStorageAttachment contains details of a unit storage attachment. 51 type UnitStorageAttachment struct { 52 // MachineId is the ID of the machine that the unit is assigned to. 53 // 54 // This is omitempty to cater for legacy results, where the machine 55 // information is not available. 56 MachineId string `yaml:"machine,omitempty" json:"machine,omitempty"` 57 58 // Location is the location of the storage attachment. 59 Location string `yaml:"location,omitempty" json:"location,omitempty"` 60 61 // TODO(axw) per-unit status when we have it in state. 62 } 63 64 // formatStorageDetails takes a set of StorageDetail and 65 // creates a mapping from storage ID to storage details. 66 func formatStorageDetails(storages []params.StorageDetails) (map[string]StorageInfo, error) { 67 if len(storages) == 0 { 68 return nil, nil 69 } 70 output := make(map[string]StorageInfo) 71 for _, details := range storages { 72 storageTag, storageInfo, err := createStorageInfo(details) 73 if err != nil { 74 return nil, errors.Trace(err) 75 } 76 output[storageTag.Id()] = storageInfo 77 } 78 return output, nil 79 } 80 81 func createStorageInfo(details params.StorageDetails) (names.StorageTag, StorageInfo, error) { 82 storageTag, err := names.ParseStorageTag(details.StorageTag) 83 if err != nil { 84 return names.StorageTag{}, StorageInfo{}, errors.Trace(err) 85 } 86 87 info := StorageInfo{ 88 Kind: details.Kind.String(), 89 Status: EntityStatus{ 90 details.Status.Status, 91 details.Status.Info, 92 // TODO(axw) we should support formatting as ISO time 93 common.FormatTime(details.Status.Since, false), 94 }, 95 Persistent: details.Persistent, 96 } 97 98 if len(details.Attachments) > 0 { 99 unitStorageAttachments := make(map[string]UnitStorageAttachment) 100 for unitTagString, attachmentDetails := range details.Attachments { 101 unitTag, err := names.ParseUnitTag(unitTagString) 102 if err != nil { 103 return names.StorageTag{}, StorageInfo{}, errors.Trace(err) 104 } 105 var machineId string 106 if attachmentDetails.MachineTag != "" { 107 machineTag, err := names.ParseMachineTag(attachmentDetails.MachineTag) 108 if err != nil { 109 return names.StorageTag{}, StorageInfo{}, errors.Trace(err) 110 } 111 machineId = machineTag.Id() 112 } 113 unitStorageAttachments[unitTag.Id()] = UnitStorageAttachment{ 114 machineId, 115 attachmentDetails.Location, 116 } 117 } 118 info.Attachments = &StorageAttachments{unitStorageAttachments} 119 } 120 121 return storageTag, info, nil 122 }