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  }