github.com/cloud-green/juju@v0.0.0-20151002100041-a00291338d3d/apiserver/diskmanager/diskmanager.go (about)

     1  // Copyright 2014 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package diskmanager
     5  
     6  import (
     7  	"github.com/juju/loggo"
     8  	"github.com/juju/names"
     9  
    10  	"github.com/juju/juju/apiserver/common"
    11  	"github.com/juju/juju/apiserver/params"
    12  	"github.com/juju/juju/state"
    13  	"github.com/juju/juju/storage"
    14  )
    15  
    16  func init() {
    17  	common.RegisterStandardFacade("DiskManager", 1, NewDiskManagerAPI)
    18  }
    19  
    20  var logger = loggo.GetLogger("juju.apiserver.diskmanager")
    21  
    22  // DiskManagerAPI provides access to the DiskManager API facade.
    23  type DiskManagerAPI struct {
    24  	st          stateInterface
    25  	authorizer  common.Authorizer
    26  	getAuthFunc common.GetAuthFunc
    27  }
    28  
    29  var getState = func(st *state.State) stateInterface {
    30  	return stateShim{st}
    31  }
    32  
    33  // NewDiskManagerAPI creates a new server-side DiskManager API facade.
    34  func NewDiskManagerAPI(
    35  	st *state.State,
    36  	resources *common.Resources,
    37  	authorizer common.Authorizer,
    38  ) (*DiskManagerAPI, error) {
    39  
    40  	if !authorizer.AuthMachineAgent() {
    41  		return nil, common.ErrPerm
    42  	}
    43  
    44  	authEntityTag := authorizer.GetAuthTag()
    45  	getAuthFunc := func() (common.AuthFunc, error) {
    46  		return func(tag names.Tag) bool {
    47  			// A machine agent can always access its own machine.
    48  			return tag == authEntityTag
    49  		}, nil
    50  	}
    51  
    52  	return &DiskManagerAPI{
    53  		st:          getState(st),
    54  		authorizer:  authorizer,
    55  		getAuthFunc: getAuthFunc,
    56  	}, nil
    57  }
    58  
    59  func (d *DiskManagerAPI) SetMachineBlockDevices(args params.SetMachineBlockDevices) (params.ErrorResults, error) {
    60  	result := params.ErrorResults{
    61  		Results: make([]params.ErrorResult, len(args.MachineBlockDevices)),
    62  	}
    63  	canAccess, err := d.getAuthFunc()
    64  	if err != nil {
    65  		return result, err
    66  	}
    67  	for i, arg := range args.MachineBlockDevices {
    68  		tag, err := names.ParseMachineTag(arg.Machine)
    69  		if err != nil {
    70  			result.Results[i].Error = common.ServerError(common.ErrPerm)
    71  			continue
    72  		}
    73  		if !canAccess(tag) {
    74  			err = common.ErrPerm
    75  		} else {
    76  			// TODO(axw) create volumes for block devices without matching
    77  			// volumes, if and only if the block device has a serial. Under
    78  			// the assumption of unique (to a machine) serial IDs, this
    79  			// gives us a guaranteed *persistently* unique way of identifying
    80  			// the volume.
    81  			//
    82  			// NOTE: we must predicate the above on there being no unprovisioned
    83  			// volume attachments for the machine, otherwise we would have
    84  			// a race between the volume attachment info being recorded and
    85  			// the diskmanager publishing block devices and erroneously creating
    86  			// volumes.
    87  			err = d.st.SetMachineBlockDevices(tag.Id(), stateBlockDeviceInfo(arg.BlockDevices))
    88  			// TODO(axw) set volume/filesystem attachment info.
    89  		}
    90  		result.Results[i].Error = common.ServerError(err)
    91  	}
    92  	return result, nil
    93  }
    94  
    95  func stateBlockDeviceInfo(devices []storage.BlockDevice) []state.BlockDeviceInfo {
    96  	result := make([]state.BlockDeviceInfo, len(devices))
    97  	for i, dev := range devices {
    98  		result[i] = state.BlockDeviceInfo{
    99  			dev.DeviceName,
   100  			dev.DeviceLinks,
   101  			dev.Label,
   102  			dev.UUID,
   103  			dev.HardwareId,
   104  			dev.BusAddress,
   105  			dev.Size,
   106  			dev.FilesystemType,
   107  			dev.InUse,
   108  			dev.MountPoint,
   109  		}
   110  	}
   111  	return result
   112  }