github.com/axw/juju@v0.0.0-20161005053422-4bd6544d08d4/apiserver/storage/shim.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/errors" 8 "gopkg.in/juju/names.v2" 9 10 "github.com/juju/juju/apiserver/common" 11 "github.com/juju/juju/apiserver/facade" 12 "github.com/juju/juju/environs" 13 "github.com/juju/juju/state" 14 "github.com/juju/juju/state/stateenvirons" 15 "github.com/juju/juju/storage/poolmanager" 16 ) 17 18 // This file contains untested shims to let us wrap state in a sensible 19 // interface and avoid writing tests that depend on mongodb. If you were 20 // to change any part of it so that it were no longer *obviously* and 21 // *trivially* correct, you would be Doing It Wrong. 22 23 func init() { 24 common.RegisterStandardFacade("Storage", 3, newAPI) 25 } 26 27 func newAPI( 28 st *state.State, 29 resources facade.Resources, 30 authorizer facade.Authorizer, 31 ) (*API, error) { 32 env, err := stateenvirons.GetNewEnvironFunc(environs.New)(st) 33 if err != nil { 34 return nil, errors.Annotate(err, "getting environ") 35 } 36 registry := stateenvirons.NewStorageProviderRegistry(env) 37 pm := poolmanager.New(state.NewStateSettings(st), registry) 38 return NewAPI(getState(st), registry, pm, resources, authorizer) 39 } 40 41 type storageAccess interface { 42 // StorageInstance is required for storage functionality. 43 StorageInstance(names.StorageTag) (state.StorageInstance, error) 44 45 // AllStorageInstances is required for storage functionality. 46 AllStorageInstances() ([]state.StorageInstance, error) 47 48 // StorageAttachments is required for storage functionality. 49 StorageAttachments(names.StorageTag) ([]state.StorageAttachment, error) 50 51 // UnitAssignedMachine is required for storage functionality. 52 UnitAssignedMachine(names.UnitTag) (names.MachineTag, error) 53 54 // FilesystemAttachment is required for storage functionality. 55 FilesystemAttachment(names.MachineTag, names.FilesystemTag) (state.FilesystemAttachment, error) 56 57 // StorageInstanceFilesystem is required for storage functionality. 58 StorageInstanceFilesystem(names.StorageTag) (state.Filesystem, error) 59 60 // StorageInstanceVolume is required for storage functionality. 61 StorageInstanceVolume(names.StorageTag) (state.Volume, error) 62 63 // VolumeAttachment is required for storage functionality. 64 VolumeAttachment(names.MachineTag, names.VolumeTag) (state.VolumeAttachment, error) 65 66 // WatchStorageAttachment is required for storage functionality. 67 WatchStorageAttachment(names.StorageTag, names.UnitTag) state.NotifyWatcher 68 69 // WatchFilesystemAttachment is required for storage functionality. 70 WatchFilesystemAttachment(names.MachineTag, names.FilesystemTag) state.NotifyWatcher 71 72 // WatchVolumeAttachment is required for storage functionality. 73 WatchVolumeAttachment(names.MachineTag, names.VolumeTag) state.NotifyWatcher 74 75 // WatchBlockDevices is required for storage functionality. 76 WatchBlockDevices(names.MachineTag) state.NotifyWatcher 77 78 // BlockDevices is required for storage functionality. 79 BlockDevices(names.MachineTag) ([]state.BlockDeviceInfo, error) 80 81 // ModelName is required for pool functionality. 82 ModelName() (string, error) 83 84 // ModelTag is required for model permission checking. 85 ModelTag() names.ModelTag 86 87 // AllVolumes is required for volume functionality. 88 AllVolumes() ([]state.Volume, error) 89 90 // VolumeAttachments is required for volume functionality. 91 VolumeAttachments(volume names.VolumeTag) ([]state.VolumeAttachment, error) 92 93 // MachineVolumeAttachments is required for volume functionality. 94 MachineVolumeAttachments(machine names.MachineTag) ([]state.VolumeAttachment, error) 95 96 // Volume is required for volume functionality. 97 Volume(tag names.VolumeTag) (state.Volume, error) 98 99 // AllFilesystems is required for filesystem functionality. 100 AllFilesystems() ([]state.Filesystem, error) 101 102 // FilesystemAttachments is required for filesystem functionality. 103 FilesystemAttachments(filesystem names.FilesystemTag) ([]state.FilesystemAttachment, error) 104 105 // MachineFilesystemAttachments is required for filesystem functionality. 106 MachineFilesystemAttachments(machine names.MachineTag) ([]state.FilesystemAttachment, error) 107 108 // Filesystem is required for filesystem functionality. 109 Filesystem(tag names.FilesystemTag) (state.Filesystem, error) 110 111 // AddStorageForUnit is required for storage add functionality. 112 AddStorageForUnit(tag names.UnitTag, name string, cons state.StorageConstraints) error 113 114 // GetBlockForType is required to block operations. 115 GetBlockForType(t state.BlockType) (state.Block, bool, error) 116 } 117 118 var getState = func(st *state.State) storageAccess { 119 return stateShim{st} 120 } 121 122 type stateShim struct { 123 *state.State 124 } 125 126 // UnitAssignedMachine returns the tag of the machine that the unit 127 // is assigned to, or an error if the unit cannot be obtained or is 128 // not assigned to a machine. 129 func (s stateShim) UnitAssignedMachine(tag names.UnitTag) (names.MachineTag, error) { 130 unit, err := s.Unit(tag.Id()) 131 if err != nil { 132 return names.MachineTag{}, errors.Trace(err) 133 } 134 mid, err := unit.AssignedMachineId() 135 if err != nil { 136 return names.MachineTag{}, errors.Trace(err) 137 } 138 return names.NewMachineTag(mid), nil 139 } 140 141 // ModelName returns the name of Juju environment, 142 // or an error if environment configuration is not retrievable. 143 func (s stateShim) ModelName() (string, error) { 144 cfg, err := s.State.ModelConfig() 145 if err != nil { 146 return "", errors.Trace(err) 147 } 148 return cfg.Name(), nil 149 }