github.com/niedbalski/juju@v0.0.0-20190215020005-8ff100488e47/provider/oracle/storage.go (about)

     1  // Copyright 2017 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package oracle
     5  
     6  import (
     7  	"github.com/juju/errors"
     8  	oci "github.com/juju/go-oracle-cloud/api"
     9  
    10  	"github.com/juju/juju/provider/oracle/common"
    11  	"github.com/juju/juju/storage"
    12  )
    13  
    14  const (
    15  	oracleStorageProviderType = storage.ProviderType("oracle")
    16  
    17  	// maxVolumeSizeInGB represents the maximum size in GiB for
    18  	// a single volume. For more information please see:
    19  	// https://docs.oracle.com/cloud/latest/stcomputecs/STCSA/op-storage-volume--post.html#request
    20  	maxVolumeSizeInGB = 2000
    21  	// minVolumeSizeInGB represents the minimum size in GiB for
    22  	// a single volume. For more information please see:
    23  	// https://docs.oracle.com/cloud/latest/stcomputecs/STCSA/op-storage-volume--post.html#request
    24  	minVolumeSizeInGB = 1
    25  	// maxDevices is the maximum number of volumes that can be attached to a single instance
    26  	// for more information, please see:
    27  	// https://docs.oracle.com/cloud/latest/stcomputecs/STCSA/op-storage-attachment--post.html#request
    28  	maxDevices = 10
    29  	// blockDevicePrefix is the default block storage prefix for an oracle
    30  	// cloud storage volume, as seen by GNU/Linux guests. For more information, please see:
    31  	// https://docs.oracle.com/cloud/latest/stcomputecs/STCSA/op-storage-attachment--post.html#request
    32  	blockDevicePrefix = "xvd"
    33  
    34  	// blockDeviceStartIndex is the base from which we start incrementing block device names
    35  	// start from 'a'. xvda will always be the root disk.
    36  	blockDeviceStartIndex = 'a'
    37  )
    38  
    39  // storageProvider implements the storage.Provider interface
    40  type storageProvider struct {
    41  	env *OracleEnviron
    42  	api StorageAPI
    43  }
    44  
    45  var _ storage.Provider = (*storageProvider)(nil)
    46  
    47  // StorageAPI defines the storage API in the oracle cloud provider
    48  // this enables the provider to talk with the storage API and make
    49  // storage specific operations
    50  type StorageAPI interface {
    51  	common.StorageVolumeAPI
    52  	common.StorageAttachmentAPI
    53  	common.Composer
    54  }
    55  
    56  func mibToGib(m uint64) uint64 {
    57  	return (m + 1023) / 1024
    58  }
    59  
    60  func (o *OracleEnviron) canAccessStorageAPI() (bool, error) {
    61  	// Check if we actually have access to the storage APIs.
    62  	_, err := o.client.AllStorageVolumes(nil)
    63  	if err != nil {
    64  		// The API usually returns a 405 error if we don't have access to that bit of the cloud
    65  		// this is something that happens for trial accounts.
    66  		if oci.IsMethodNotAllowed(err) {
    67  			return false, nil
    68  		}
    69  		return false, errors.Trace(err)
    70  	}
    71  	return true, nil
    72  }
    73  
    74  // StorageProviderTypes implements storage.ProviderRegistry.
    75  func (o *OracleEnviron) StorageProviderTypes() ([]storage.ProviderType, error) {
    76  	if access, err := o.canAccessStorageAPI(); access {
    77  		return []storage.ProviderType{oracleStorageProviderType}, nil
    78  	} else {
    79  		return nil, errors.Trace(err)
    80  	}
    81  }
    82  
    83  // StorageProvider implements storage.ProviderRegistry.
    84  func (o *OracleEnviron) StorageProvider(t storage.ProviderType) (storage.Provider, error) {
    85  	access, err := o.canAccessStorageAPI()
    86  	if err != nil {
    87  		return nil, errors.Trace(err)
    88  	}
    89  	if access && t == oracleStorageProviderType {
    90  		return &storageProvider{
    91  			env: o,
    92  			api: o.client,
    93  		}, nil
    94  	}
    95  
    96  	return nil, errors.NotFoundf("storage provider %q", t)
    97  }