yunion.io/x/cloudmux@v0.3.10-0-alpha.1/pkg/multicloud/objectstore/objectstore.go (about)

     1  // Copyright 2019 Yunion
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package objectstore
    16  
    17  import (
    18  	"net/url"
    19  	"os"
    20  	"strings"
    21  
    22  	"yunion.io/x/jsonutils"
    23  	"yunion.io/x/log"
    24  	"yunion.io/x/pkg/errors"
    25  	"yunion.io/x/pkg/util/secrules"
    26  	"yunion.io/x/s3cli"
    27  
    28  	api "yunion.io/x/cloudmux/pkg/apis/compute"
    29  	"yunion.io/x/onecloud/pkg/cloudcommon/object"
    30  	"yunion.io/x/cloudmux/pkg/cloudprovider"
    31  	"yunion.io/x/cloudmux/pkg/multicloud"
    32  	"yunion.io/x/onecloud/pkg/util/httputils"
    33  )
    34  
    35  type ObjectStoreClientConfig struct {
    36  	cpcfg cloudprovider.ProviderConfig
    37  
    38  	endpoint     string
    39  	accessKey    string
    40  	accessSecret string
    41  
    42  	debug bool
    43  }
    44  
    45  func NewObjectStoreClientConfig(endpoint, accessKey, accessSecret string) *ObjectStoreClientConfig {
    46  	cfg := &ObjectStoreClientConfig{
    47  		endpoint:     endpoint,
    48  		accessKey:    accessKey,
    49  		accessSecret: accessSecret,
    50  	}
    51  	return cfg
    52  }
    53  
    54  func (cfg *ObjectStoreClientConfig) CloudproviderConfig(cpcfg cloudprovider.ProviderConfig) *ObjectStoreClientConfig {
    55  	cfg.cpcfg = cpcfg
    56  	return cfg
    57  }
    58  
    59  func (cfg *ObjectStoreClientConfig) Debug(debug bool) *ObjectStoreClientConfig {
    60  	cfg.debug = debug
    61  	return cfg
    62  }
    63  
    64  func (cfg *ObjectStoreClientConfig) GetCloudproviderConfig() cloudprovider.ProviderConfig {
    65  	return cfg.cpcfg
    66  }
    67  
    68  func (cfg *ObjectStoreClientConfig) GetEndpoint() string {
    69  	return cfg.endpoint
    70  }
    71  
    72  func (cfg *ObjectStoreClientConfig) GetAccessKey() string {
    73  	return cfg.accessKey
    74  }
    75  
    76  func (cfg *ObjectStoreClientConfig) GetAccessSecret() string {
    77  	return cfg.accessSecret
    78  }
    79  
    80  func (cfg *ObjectStoreClientConfig) GetDebug() bool {
    81  	return cfg.debug
    82  }
    83  
    84  type SObjectStoreClient struct {
    85  	object.SObject
    86  
    87  	*ObjectStoreClientConfig
    88  
    89  	cloudprovider.SFakeOnPremiseRegion
    90  	multicloud.SRegion
    91  
    92  	ownerId   string
    93  	ownerName string
    94  
    95  	iBuckets []cloudprovider.ICloudBucket
    96  
    97  	client *s3cli.Client
    98  }
    99  
   100  func NewObjectStoreClient(cfg *ObjectStoreClientConfig) (*SObjectStoreClient, error) {
   101  	return NewObjectStoreClientAndFetch(cfg, true)
   102  }
   103  
   104  func NewObjectStoreClientAndFetch(cfg *ObjectStoreClientConfig, doFetch bool) (*SObjectStoreClient, error) {
   105  	client := SObjectStoreClient{
   106  		ObjectStoreClientConfig: cfg,
   107  	}
   108  	parts, err := url.Parse(cfg.endpoint)
   109  	if err != nil {
   110  		return nil, errors.Wrap(err, "url.Parse endpoint")
   111  	}
   112  	useSsl := false
   113  	if parts.Scheme == "https" {
   114  		useSsl = true
   115  	}
   116  	cli, err := s3cli.New(
   117  		parts.Host,
   118  		client.accessKey,
   119  		client.accessSecret,
   120  		useSsl,
   121  		client.debug,
   122  	)
   123  	if err != nil {
   124  		return nil, errors.Wrap(err, "minio.New")
   125  	}
   126  
   127  	tr := httputils.GetTransport(true)
   128  	tr.Proxy = cfg.cpcfg.ProxyFunc
   129  	cli.SetCustomTransport(tr)
   130  
   131  	client.client = cli
   132  	client.SetVirtualObject(&client)
   133  
   134  	if client.debug {
   135  		cli.TraceOn(os.Stderr)
   136  	}
   137  
   138  	if doFetch {
   139  		err = client.FetchBuckets()
   140  		if err != nil {
   141  			return nil, errors.Wrap(err, "fetchBuckets")
   142  		}
   143  	}
   144  
   145  	return &client, nil
   146  }
   147  
   148  func (cli *SObjectStoreClient) GetSubAccounts() ([]cloudprovider.SSubAccount, error) {
   149  	subAccount := cloudprovider.SSubAccount{
   150  		Account:      cli.accessKey,
   151  		Name:         cli.cpcfg.Name,
   152  		HealthStatus: api.CLOUD_PROVIDER_HEALTH_NORMAL,
   153  	}
   154  	return []cloudprovider.SSubAccount{subAccount}, nil
   155  }
   156  
   157  func (cli *SObjectStoreClient) GetAccountId() string {
   158  	return cli.ownerId
   159  }
   160  
   161  func (cli *SObjectStoreClient) GetIRegion() cloudprovider.ICloudRegion {
   162  	return cli.GetVirtualObject().(cloudprovider.ICloudRegion)
   163  }
   164  
   165  func (cli *SObjectStoreClient) GetIBucketProvider() IBucketProvider {
   166  	return cli.GetVirtualObject().(IBucketProvider)
   167  }
   168  
   169  func (cli *SObjectStoreClient) GetI18n() cloudprovider.SModelI18nTable {
   170  	table := cloudprovider.SModelI18nTable{}
   171  	table["name"] = cloudprovider.NewSModelI18nEntry(cli.GetName()).CN(cli.GetName())
   172  	return table
   173  }
   174  
   175  func (cli *SObjectStoreClient) GetVersion() string {
   176  	return ""
   177  }
   178  
   179  func (cli *SObjectStoreClient) About() jsonutils.JSONObject {
   180  	about := jsonutils.NewDict()
   181  	return about
   182  }
   183  
   184  func (cli *SObjectStoreClient) GetProvider() string {
   185  	return api.CLOUD_PROVIDER_GENERICS3
   186  }
   187  
   188  func (cli *SObjectStoreClient) GetCloudEnv() string {
   189  	return ""
   190  }
   191  
   192  ////////////////////////////// IBucketProvider //////////////////////////////
   193  
   194  func (cli *SObjectStoreClient) NewBucket(bucket s3cli.BucketInfo) cloudprovider.ICloudBucket {
   195  	return &SBucket{
   196  		client:    cli.GetIBucketProvider(),
   197  		Name:      bucket.Name,
   198  		CreatedAt: bucket.CreationDate,
   199  	}
   200  }
   201  
   202  func (cli *SObjectStoreClient) GetEndpoint() string {
   203  	return cli.endpoint
   204  }
   205  
   206  func (cli *SObjectStoreClient) S3Client() *s3cli.Client {
   207  	return cli.client
   208  }
   209  
   210  func (cli *SObjectStoreClient) GetClientRC() map[string]string {
   211  	return map[string]string{
   212  		"S3_ACCESS_KEY": cli.accessKey,
   213  		"S3_SECRET":     cli.accessSecret,
   214  		"S3_ACCESS_URL": cli.endpoint,
   215  		"S3_BACKEND":    api.CLOUD_PROVIDER_GENERICS3,
   216  	}
   217  }
   218  
   219  ///////////////////////////////// fake impletementations //////////////////////
   220  
   221  func (cli *SObjectStoreClient) GetIZones() ([]cloudprovider.ICloudZone, error) {
   222  	return nil, cloudprovider.ErrNotSupported
   223  }
   224  
   225  func (cli *SObjectStoreClient) GetIVpcs() ([]cloudprovider.ICloudVpc, error) {
   226  	return nil, cloudprovider.ErrNotSupported
   227  }
   228  
   229  func (cli *SObjectStoreClient) GetIEips() ([]cloudprovider.ICloudEIP, error) {
   230  	return nil, cloudprovider.ErrNotSupported
   231  }
   232  
   233  func (cli *SObjectStoreClient) GetIVpcById(id string) (cloudprovider.ICloudVpc, error) {
   234  	return nil, cloudprovider.ErrNotSupported
   235  }
   236  
   237  func (cli *SObjectStoreClient) GetIZoneById(id string) (cloudprovider.ICloudZone, error) {
   238  	return nil, cloudprovider.ErrNotSupported
   239  }
   240  
   241  func (cli *SObjectStoreClient) GetIEipById(id string) (cloudprovider.ICloudEIP, error) {
   242  	return nil, cloudprovider.ErrNotSupported
   243  }
   244  
   245  func (cli *SObjectStoreClient) GetIVMById(id string) (cloudprovider.ICloudVM, error) {
   246  	return nil, cloudprovider.ErrNotSupported
   247  }
   248  
   249  func (cli *SObjectStoreClient) GetIDiskById(id string) (cloudprovider.ICloudDisk, error) {
   250  	return nil, cloudprovider.ErrNotSupported
   251  }
   252  
   253  func (cli *SObjectStoreClient) SyncSecurityGroup(secgroupId string, vpcId string, name string, desc string, rules []secrules.SecurityRule) (string, error) {
   254  	return "", cloudprovider.ErrNotSupported
   255  }
   256  
   257  func (cli *SObjectStoreClient) CreateIVpc(opts *cloudprovider.VpcCreateOptions) (cloudprovider.ICloudVpc, error) {
   258  	return nil, cloudprovider.ErrNotSupported
   259  }
   260  
   261  func (cli *SObjectStoreClient) CreateEIP(eip *cloudprovider.SEip) (cloudprovider.ICloudEIP, error) {
   262  	return nil, cloudprovider.ErrNotSupported
   263  }
   264  
   265  func (cli *SObjectStoreClient) GetISnapshots() ([]cloudprovider.ICloudSnapshot, error) {
   266  	return nil, cloudprovider.ErrNotSupported
   267  }
   268  
   269  func (cli *SObjectStoreClient) GetISnapshotById(snapshotId string) (cloudprovider.ICloudSnapshot, error) {
   270  	return nil, cloudprovider.ErrNotSupported
   271  }
   272  
   273  func (cli *SObjectStoreClient) CreateSnapshotPolicy(*cloudprovider.SnapshotPolicyInput) (string, error) {
   274  	return "", cloudprovider.ErrNotSupported
   275  }
   276  
   277  func (cli *SObjectStoreClient) DeleteSnapshotPolicy(string) error {
   278  	return cloudprovider.ErrNotSupported
   279  }
   280  
   281  func (cli *SObjectStoreClient) ApplySnapshotPolicyToDisks(snapshotPolicyId string, diskId string) error {
   282  	return cloudprovider.ErrNotSupported
   283  }
   284  
   285  func (cli *SObjectStoreClient) CancelSnapshotPolicyToDisks(snapshotPolicyId string, diskId string) error {
   286  	return cloudprovider.ErrNotSupported
   287  }
   288  
   289  func (cli *SObjectStoreClient) GetISnapshotPolicies() ([]cloudprovider.ICloudSnapshotPolicy, error) {
   290  	return nil, cloudprovider.ErrNotSupported
   291  }
   292  
   293  func (cli *SObjectStoreClient) GetISnapshotPolicyById(snapshotPolicyId string) (cloudprovider.ICloudSnapshotPolicy, error) {
   294  	return nil, cloudprovider.ErrNotSupported
   295  }
   296  
   297  func (cli *SObjectStoreClient) GetIHosts() ([]cloudprovider.ICloudHost, error) {
   298  	return nil, cloudprovider.ErrNotSupported
   299  }
   300  
   301  func (cli *SObjectStoreClient) GetIHostById(id string) (cloudprovider.ICloudHost, error) {
   302  	return nil, cloudprovider.ErrNotSupported
   303  }
   304  
   305  func (cli *SObjectStoreClient) GetIStorages() ([]cloudprovider.ICloudStorage, error) {
   306  	return nil, cloudprovider.ErrNotSupported
   307  }
   308  
   309  func (cli *SObjectStoreClient) GetIStorageById(id string) (cloudprovider.ICloudStorage, error) {
   310  	return nil, cloudprovider.ErrNotSupported
   311  }
   312  
   313  func (cli *SObjectStoreClient) GetIStoragecaches() ([]cloudprovider.ICloudStoragecache, error) {
   314  	return nil, cloudprovider.ErrNotSupported
   315  }
   316  
   317  func (cli *SObjectStoreClient) GetIStoragecacheById(id string) (cloudprovider.ICloudStoragecache, error) {
   318  	return nil, cloudprovider.ErrNotSupported
   319  }
   320  
   321  func (cli *SObjectStoreClient) GetILoadBalancers() ([]cloudprovider.ICloudLoadbalancer, error) {
   322  	return nil, cloudprovider.ErrNotSupported
   323  }
   324  
   325  func (cli *SObjectStoreClient) GetILoadBalancerAcls() ([]cloudprovider.ICloudLoadbalancerAcl, error) {
   326  	return nil, cloudprovider.ErrNotSupported
   327  }
   328  
   329  func (cli *SObjectStoreClient) GetILoadBalancerCertificates() ([]cloudprovider.ICloudLoadbalancerCertificate, error) {
   330  	return nil, cloudprovider.ErrNotSupported
   331  }
   332  
   333  func (cli *SObjectStoreClient) GetILoadBalancerById(loadbalancerId string) (cloudprovider.ICloudLoadbalancer, error) {
   334  	return nil, cloudprovider.ErrNotSupported
   335  }
   336  
   337  func (cli *SObjectStoreClient) GetILoadBalancerAclById(aclId string) (cloudprovider.ICloudLoadbalancerAcl, error) {
   338  	return nil, cloudprovider.ErrNotSupported
   339  }
   340  
   341  func (cli *SObjectStoreClient) GetILoadBalancerCertificateById(certId string) (cloudprovider.ICloudLoadbalancerCertificate, error) {
   342  	return nil, cloudprovider.ErrNotSupported
   343  }
   344  
   345  func (cli *SObjectStoreClient) CreateILoadBalancer(loadbalancer *cloudprovider.SLoadbalancer) (cloudprovider.ICloudLoadbalancer, error) {
   346  	return nil, cloudprovider.ErrNotSupported
   347  }
   348  
   349  func (cli *SObjectStoreClient) CreateILoadBalancerAcl(acl *cloudprovider.SLoadbalancerAccessControlList) (cloudprovider.ICloudLoadbalancerAcl, error) {
   350  	return nil, cloudprovider.ErrNotSupported
   351  }
   352  
   353  func (cli *SObjectStoreClient) CreateILoadBalancerCertificate(cert *cloudprovider.SLoadbalancerCertificate) (cloudprovider.ICloudLoadbalancerCertificate, error) {
   354  	return nil, cloudprovider.ErrNotSupported
   355  }
   356  
   357  func (cli *SObjectStoreClient) GetISkus() ([]cloudprovider.ICloudSku, error) {
   358  	return nil, cloudprovider.ErrNotSupported
   359  }
   360  
   361  func (cli *SObjectStoreClient) CreateISku(opts *cloudprovider.SServerSkuCreateOption) (cloudprovider.ICloudSku, error) {
   362  	return nil, cloudprovider.ErrNotSupported
   363  }
   364  
   365  ////////////////////////////////// S3 API ///////////////////////////////////
   366  
   367  func (cli *SObjectStoreClient) GetIBuckets() ([]cloudprovider.ICloudBucket, error) {
   368  	return cli.getIBuckets()
   369  }
   370  
   371  func (self *SObjectStoreClient) invalidateIBuckets() {
   372  	self.iBuckets = nil
   373  }
   374  
   375  func (self *SObjectStoreClient) getIBuckets() ([]cloudprovider.ICloudBucket, error) {
   376  	if self.iBuckets == nil {
   377  		err := self.FetchBuckets()
   378  		if err != nil {
   379  			return nil, errors.Wrap(err, "fetchBuckets")
   380  		}
   381  	}
   382  	return self.iBuckets, nil
   383  }
   384  
   385  func (cli *SObjectStoreClient) FetchBuckets() error {
   386  	result, err := cli.client.ListBuckets()
   387  	if err != nil {
   388  		return errors.Wrap(err, "client.ListBuckets")
   389  	}
   390  	cli.ownerId = result.Owner.ID
   391  	cli.ownerName = result.Owner.DisplayName
   392  	buckets := result.Buckets.Bucket
   393  	cli.iBuckets = make([]cloudprovider.ICloudBucket, len(buckets))
   394  	for i := range buckets {
   395  		b := cli.GetIBucketProvider().NewBucket(buckets[i])
   396  		cli.iBuckets[i] = b
   397  	}
   398  	return nil
   399  }
   400  
   401  func (cli *SObjectStoreClient) CreateIBucket(name string, storageClass string, acl string) error {
   402  	err := cli.client.MakeBucket(name, "")
   403  	if err != nil {
   404  		return errors.Wrap(err, "MakeBucket")
   405  	}
   406  	cli.invalidateIBuckets()
   407  	return nil
   408  }
   409  
   410  func minioErrCode(err error) int {
   411  	if srvErr, ok := err.(s3cli.ErrorResponse); ok {
   412  		return srvErr.StatusCode
   413  	}
   414  	if srvErr, ok := err.(*s3cli.ErrorResponse); ok {
   415  		return srvErr.StatusCode
   416  	}
   417  	return -1
   418  }
   419  
   420  func (cli *SObjectStoreClient) DeleteIBucket(name string) error {
   421  	err := cli.client.RemoveBucket(name)
   422  	if err != nil {
   423  		if minioErrCode(err) == 404 {
   424  			return nil
   425  		}
   426  		return errors.Wrap(err, "RemoveBucket")
   427  	}
   428  	cli.invalidateIBuckets()
   429  	return nil
   430  }
   431  
   432  func (cli *SObjectStoreClient) GetIBucketLocation(name string) (string, error) {
   433  	info, err := cli.client.GetBucketLocation(name)
   434  	if err != nil {
   435  		return "", errors.Wrap(err, "GetBucketLocation")
   436  	}
   437  	return info, nil
   438  }
   439  
   440  func (cli *SObjectStoreClient) GetIBucketWebsite(name string) (string, error) {
   441  	info, err := cli.client.GetBucketWebsite(name)
   442  	if err != nil {
   443  		return "", errors.Wrap(err, "GetBucketWebsite")
   444  	}
   445  	return info, nil
   446  }
   447  
   448  func (cli *SObjectStoreClient) GetIBucketReferer(name string) (string, error) {
   449  	info, err := cli.client.GetBucketReferer(name)
   450  	if err != nil {
   451  		return "", errors.Wrap(err, "GetBucketReferer")
   452  	}
   453  	return info, nil
   454  }
   455  
   456  func (cli *SObjectStoreClient) GetIBucketCors(name string) (string, error) {
   457  	info, err := cli.client.GetBucketCors(name)
   458  	if err != nil {
   459  		return "", errors.Wrap(err, "GetBucketCors")
   460  	}
   461  	return info, nil
   462  }
   463  
   464  func (cli *SObjectStoreClient) GetIBucketLogging(name string) (*s3cli.BucketLoggingStatus, error) {
   465  	info, err := cli.client.GetBucketLogging(name)
   466  	if err != nil {
   467  		return nil, errors.Wrap(err, "GetBucketLogging")
   468  	}
   469  	return info, nil
   470  }
   471  
   472  func (cli *SObjectStoreClient) SetIBucketLogging(name string, target string, targetPrefix string, email string) error {
   473  	conf := s3cli.BucketLoggingStatus{}
   474  	if len(target) > 0 {
   475  		conf.LoggingEnabled.TargetBucket = target
   476  		conf.LoggingEnabled.TargetPrefix = targetPrefix
   477  		conf.LoggingEnabled.TargetGrants.Grant = []s3cli.Grant{
   478  			{
   479  				Grantee: s3cli.Grantee{
   480  					Type:         s3cli.GRANTEE_TYPE_EMAIL,
   481  					EmailAddress: email,
   482  				},
   483  				Permission: s3cli.PERMISSION_FULL_CONTROL,
   484  			},
   485  		}
   486  	}
   487  	err := cli.client.SetBucketLogging(name, conf)
   488  	if err != nil {
   489  		return errors.Wrap(err, "SetBucketLogging")
   490  	}
   491  	return nil
   492  }
   493  
   494  func (cli *SObjectStoreClient) GetIBucketInfo(name string) (string, error) {
   495  	info, err := cli.client.GetBucketInfo(name)
   496  	if err != nil {
   497  		return "", errors.Wrap(err, "GetBucketInfo")
   498  	}
   499  	return info, nil
   500  }
   501  
   502  func (cli *SObjectStoreClient) GetIBucketAcl(name string) (cloudprovider.TBucketACLType, error) {
   503  	acl, err := cli.client.GetBucketAcl(name)
   504  	if err != nil {
   505  		return "", errors.Wrap(err, "GetBucketAcl")
   506  	}
   507  	return cloudprovider.TBucketACLType(acl.GetCannedACL()), nil
   508  }
   509  
   510  func (cli *SObjectStoreClient) SetIBucketAcl(name string, cannedAcl cloudprovider.TBucketACLType) error {
   511  	acl := s3cli.CannedAcl(cli.ownerId, cli.ownerName, string(cannedAcl))
   512  	err := cli.client.SetBucketAcl(name, acl)
   513  	if err != nil {
   514  		if strings.Contains(err.Error(), "not implemented") {
   515  			// ignore not implemented error
   516  			return nil // cloudprovider.ErrNotImplemented
   517  		} else {
   518  			return errors.Wrap(err, "SetBucketAcl")
   519  		}
   520  	}
   521  	return nil
   522  }
   523  
   524  func (cli *SObjectStoreClient) GetObjectAcl(bucket, key string) (cloudprovider.TBucketACLType, error) {
   525  	acl, err := cli.client.GetObjectACL(bucket, key)
   526  	if err != nil {
   527  		return "", errors.Wrap(err, "GetBucketAcl")
   528  	}
   529  	return cloudprovider.TBucketACLType(acl.GetCannedACL()), nil
   530  }
   531  
   532  func (cli *SObjectStoreClient) SetObjectAcl(bucket, key string, cannedAcl cloudprovider.TBucketACLType) error {
   533  	acl := s3cli.CannedAcl(cli.ownerId, cli.ownerName, string(cannedAcl))
   534  	err := cli.client.SetObjectAcl(bucket, key, acl)
   535  	if err != nil {
   536  		return errors.Wrap(err, "SetObjectAcl")
   537  	}
   538  	return nil
   539  }
   540  
   541  func (cli *SObjectStoreClient) GetIBucketPolicy(name string) (string, error) {
   542  	policy, err := cli.client.GetBucketPolicy(name)
   543  	if err != nil {
   544  		return "", errors.Wrap(err, "GetBucketPolicy")
   545  	}
   546  	return policy, nil
   547  }
   548  
   549  func (cli *SObjectStoreClient) SetIBucketPolicy(name string, policy string) error {
   550  	err := cli.client.SetBucketPolicy(name, policy)
   551  	if err != nil {
   552  		return errors.Wrap(err, "SetBucketPolicy")
   553  	}
   554  	return nil
   555  }
   556  
   557  func (cli *SObjectStoreClient) GetIBucketLiftcycle(name string) (string, error) {
   558  	liftcycle, err := cli.client.GetBucketLifecycle(name)
   559  	if err != nil {
   560  		return "", errors.Wrap(err, "GetBucketLifecycle")
   561  	}
   562  	return liftcycle, nil
   563  }
   564  
   565  func (cli *SObjectStoreClient) IBucketExist(name string) (bool, error) {
   566  	exist, header, err := cli.client.BucketExists(name)
   567  	if err != nil {
   568  		return false, errors.Wrap(err, "BucketExists")
   569  	}
   570  	if header != nil {
   571  		log.Debugf("header: %s", jsonutils.Marshal(header))
   572  	}
   573  	return exist, nil
   574  }
   575  
   576  func (cli *SObjectStoreClient) GetIBucketById(name string) (cloudprovider.ICloudBucket, error) {
   577  	return cloudprovider.GetIBucketById(cli, name)
   578  }
   579  
   580  func (cli *SObjectStoreClient) GetIBucketByName(name string) (cloudprovider.ICloudBucket, error) {
   581  	return cli.GetIBucketById(name)
   582  }
   583  
   584  func (self *SObjectStoreClient) GetCapabilities() []string {
   585  	caps := []string{
   586  		// cloudprovider.CLOUD_CAPABILITY_PROJECT,
   587  		// cloudprovider.CLOUD_CAPABILITY_COMPUTE,
   588  		// cloudprovider.CLOUD_CAPABILITY_NETWORK,
   589  		// cloudprovider.CLOUD_CAPABILITY_LOADBALANCER,
   590  		cloudprovider.CLOUD_CAPABILITY_OBJECTSTORE,
   591  		// cloudprovider.CLOUD_CAPABILITY_RDS,
   592  		// cloudprovider.CLOUD_CAPABILITY_CACHE,
   593  		// cloudprovider.CLOUD_CAPABILITY_EVENT,
   594  	}
   595  	return caps
   596  }