yunion.io/x/cloudmux@v0.3.10-0-alpha.1/pkg/multicloud/remotefile/remotefile.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 remotefile
    16  
    17  import (
    18  	"context"
    19  	"fmt"
    20  	"net/http"
    21  
    22  	"yunion.io/x/jsonutils"
    23  
    24  	api "yunion.io/x/cloudmux/pkg/apis/compute"
    25  	"yunion.io/x/cloudmux/pkg/cloudprovider"
    26  	"yunion.io/x/onecloud/pkg/util/httputils"
    27  )
    28  
    29  const (
    30  	CLOUD_PROVIDER_REMOTEFILE = api.CLOUD_PROVIDER_REMOTEFILE
    31  )
    32  
    33  type RemoteFileClientConfig struct {
    34  	cpcfg cloudprovider.ProviderConfig
    35  
    36  	url      string
    37  	username string
    38  	password string
    39  
    40  	client *http.Client
    41  
    42  	projects  []SProject
    43  	regions   []SRegion
    44  	zones     []SZone
    45  	wires     []SWire
    46  	networks  []SNetwork
    47  	storages  []SStorage
    48  	disks     []SDisk
    49  	hosts     []SHost
    50  	vpcs      []SVpc
    51  	vms       []SInstance
    52  	buckets   []SBucket
    53  	eips      []SEip
    54  	rds       []SDBInstance
    55  	lbs       []SLoadbalancer
    56  	misc      []SMisc
    57  	secgroups []SSecurityGroup
    58  	metrics   map[string]interface{}
    59  
    60  	debug bool
    61  }
    62  
    63  func NewRemoteFileClientConfig(url, username, password string) *RemoteFileClientConfig {
    64  	cfg := &RemoteFileClientConfig{
    65  		url:      url,
    66  		username: username,
    67  		password: password,
    68  	}
    69  	return cfg
    70  }
    71  
    72  func (cfg *RemoteFileClientConfig) CloudproviderConfig(cpcfg cloudprovider.ProviderConfig) *RemoteFileClientConfig {
    73  	cfg.cpcfg = cpcfg
    74  	return cfg
    75  }
    76  
    77  func (cfg *RemoteFileClientConfig) Debug(debug bool) *RemoteFileClientConfig {
    78  	cfg.debug = debug
    79  	return cfg
    80  }
    81  
    82  type SRemoteFileClient struct {
    83  	*RemoteFileClientConfig
    84  }
    85  
    86  func NewRemoteFileClient(cfg *RemoteFileClientConfig) (*SRemoteFileClient, error) {
    87  	cli := &SRemoteFileClient{
    88  		RemoteFileClientConfig: cfg,
    89  	}
    90  	cli.client = httputils.GetDefaultClient()
    91  	if cli.cpcfg.ProxyFunc != nil {
    92  		httputils.SetClientProxyFunc(cli.client, cli.cpcfg.ProxyFunc)
    93  	}
    94  	_, err := cli.GetRegions()
    95  	return cli, err
    96  }
    97  
    98  func (cli *SRemoteFileClient) GetCloudRegionExternalIdPrefix() string {
    99  	return fmt.Sprintf("%s/%s/", CLOUD_PROVIDER_REMOTEFILE, cli.cpcfg.Id)
   100  }
   101  
   102  func (cli *SRemoteFileClient) GetSubAccounts() ([]cloudprovider.SSubAccount, error) {
   103  	subAccount := cloudprovider.SSubAccount{
   104  		Account: cli.cpcfg.Id,
   105  		Name:    cli.cpcfg.Name,
   106  
   107  		HealthStatus: api.CLOUD_PROVIDER_HEALTH_NORMAL,
   108  	}
   109  	return []cloudprovider.SSubAccount{subAccount}, nil
   110  }
   111  
   112  func (self *SRemoteFileClient) _url(res string) string {
   113  	return fmt.Sprintf("%s/%s.json", self.url, res)
   114  }
   115  
   116  func (self *SRemoteFileClient) get(res string) (jsonutils.JSONObject, error) {
   117  	_, resp, err := httputils.JSONRequest(self.client, context.Background(), httputils.GET, self._url(res), nil, nil, self.debug)
   118  	if err != nil {
   119  		return nil, err
   120  	}
   121  	return resp, nil
   122  }
   123  
   124  func (self *SRemoteFileClient) GetRegions() ([]SRegion, error) {
   125  	if len(self.regions) > 0 {
   126  		return self.regions, nil
   127  	}
   128  	self.regions = []SRegion{}
   129  	resp, err := self.get("regions")
   130  	if err != nil {
   131  		return nil, err
   132  	}
   133  	return self.regions, resp.Unmarshal(&self.regions)
   134  }
   135  
   136  func (self *SRemoteFileClient) GetVpcs() ([]SVpc, error) {
   137  	if len(self.vpcs) > 0 {
   138  		return self.vpcs, nil
   139  	}
   140  	self.vpcs = []SVpc{}
   141  	resp, err := self.get("vpcs")
   142  	if err != nil {
   143  		return nil, err
   144  	}
   145  	return self.vpcs, resp.Unmarshal(&self.vpcs)
   146  }
   147  
   148  func (self *SRemoteFileClient) GetMisc() ([]SMisc, error) {
   149  	if len(self.misc) > 0 {
   150  		return self.misc, nil
   151  	}
   152  	self.misc = []SMisc{}
   153  	resp, err := self.get("misc")
   154  	if err != nil {
   155  		return nil, err
   156  	}
   157  	return self.misc, resp.Unmarshal(&self.misc)
   158  }
   159  
   160  func (self *SRemoteFileClient) GetSecgroups() ([]SSecurityGroup, error) {
   161  	if len(self.secgroups) > 0 {
   162  		return self.secgroups, nil
   163  	}
   164  	self.secgroups = []SSecurityGroup{}
   165  	resp, err := self.get("secgroups")
   166  	if err != nil {
   167  		return nil, err
   168  	}
   169  	return self.secgroups, resp.Unmarshal(&self.secgroups)
   170  }
   171  
   172  func (self *SRemoteFileClient) GetInstances() ([]SInstance, error) {
   173  	if len(self.vms) > 0 {
   174  		return self.vms, nil
   175  	}
   176  	self.vms = []SInstance{}
   177  	resp, err := self.get("instances")
   178  	if err != nil {
   179  		return nil, err
   180  	}
   181  	return self.vms, resp.Unmarshal(&self.vms)
   182  }
   183  
   184  func (self *SRemoteFileClient) GetBuckets() ([]SBucket, error) {
   185  	if len(self.buckets) > 0 {
   186  		return self.buckets, nil
   187  	}
   188  	self.buckets = []SBucket{}
   189  	resp, err := self.get("buckets")
   190  	if err != nil {
   191  		return nil, err
   192  	}
   193  	return self.buckets, resp.Unmarshal(&self.buckets)
   194  }
   195  
   196  func (self *SRemoteFileClient) GetEips() ([]SEip, error) {
   197  	if len(self.eips) > 0 {
   198  		return self.eips, nil
   199  	}
   200  	self.eips = []SEip{}
   201  	resp, err := self.get("eips")
   202  	if err != nil {
   203  		return nil, err
   204  	}
   205  	return self.eips, resp.Unmarshal(&self.eips)
   206  }
   207  
   208  func (self *SRemoteFileClient) GetDBInstances() ([]SDBInstance, error) {
   209  	if len(self.rds) > 0 {
   210  		return self.rds, nil
   211  	}
   212  	self.rds = []SDBInstance{}
   213  	resp, err := self.get("dbinstances")
   214  	if err != nil {
   215  		return nil, err
   216  	}
   217  	return self.rds, resp.Unmarshal(&self.rds)
   218  }
   219  
   220  func (self *SRemoteFileClient) GetLoadbalancers() ([]SLoadbalancer, error) {
   221  	if len(self.lbs) > 0 {
   222  		return self.lbs, nil
   223  	}
   224  	self.lbs = []SLoadbalancer{}
   225  	resp, err := self.get("loadbalancers")
   226  	if err != nil {
   227  		return nil, err
   228  	}
   229  	return self.lbs, resp.Unmarshal(&self.lbs)
   230  }
   231  
   232  func (self *SRemoteFileClient) GetIRegions() []cloudprovider.ICloudRegion {
   233  	ret := []cloudprovider.ICloudRegion{}
   234  	for i := range self.regions {
   235  		self.regions[i].client = self
   236  		ret = append(ret, &self.regions[i])
   237  	}
   238  	return ret
   239  }
   240  
   241  func (self *SRemoteFileClient) GetIRegionById(id string) (cloudprovider.ICloudRegion, error) {
   242  	regions := self.GetIRegions()
   243  	for i := range regions {
   244  		if regions[i].GetGlobalId() == id {
   245  			return regions[i], nil
   246  		}
   247  	}
   248  	return nil, cloudprovider.ErrNotFound
   249  }
   250  
   251  func (self *SRemoteFileClient) GetZones() ([]SZone, error) {
   252  	if len(self.zones) > 0 {
   253  		return self.zones, nil
   254  	}
   255  	self.zones = []SZone{}
   256  	resp, err := self.get("zones")
   257  	if err != nil {
   258  		return nil, err
   259  	}
   260  	return self.zones, resp.Unmarshal(&self.zones)
   261  }
   262  
   263  func (self *SRemoteFileClient) GetHosts() ([]SHost, error) {
   264  	if len(self.hosts) > 0 {
   265  		return self.hosts, nil
   266  	}
   267  	self.hosts = []SHost{}
   268  	resp, err := self.get("hosts")
   269  	if err != nil {
   270  		return nil, err
   271  	}
   272  	return self.hosts, resp.Unmarshal(&self.hosts)
   273  }
   274  
   275  func (self *SRemoteFileClient) GetStorages() ([]SStorage, error) {
   276  	if len(self.storages) > 0 {
   277  		return self.storages, nil
   278  	}
   279  	self.storages = []SStorage{}
   280  	resp, err := self.get("storages")
   281  	if err != nil {
   282  		return nil, err
   283  	}
   284  	return self.storages, resp.Unmarshal(&self.storages)
   285  }
   286  
   287  func (self *SRemoteFileClient) getMetrics(resourceType cloudprovider.TResourceType, metricType cloudprovider.TMetricType) ([]cloudprovider.MetricValues, error) {
   288  	ret := []cloudprovider.MetricValues{}
   289  	res := fmt.Sprintf("%s/%s", resourceType, metricType)
   290  	if self.metrics == nil {
   291  		self.metrics = map[string]interface{}{}
   292  		resp, err := self.get("metrics")
   293  		if err != nil {
   294  			return nil, err
   295  		}
   296  		err = resp.Unmarshal(self.metrics)
   297  		if err != nil {
   298  			return nil, err
   299  		}
   300  	}
   301  	values, ok := self.metrics[res]
   302  	if ok {
   303  		jsonutils.Update(&ret, values)
   304  	}
   305  	return ret, nil
   306  }
   307  
   308  func (self *SRemoteFileClient) GetWires() ([]SWire, error) {
   309  	if len(self.wires) > 0 {
   310  		return self.wires, nil
   311  	}
   312  	self.wires = []SWire{}
   313  	resp, err := self.get("wires")
   314  	if err != nil {
   315  		return nil, err
   316  	}
   317  	return self.wires, resp.Unmarshal(&self.wires)
   318  }
   319  
   320  func (self *SRemoteFileClient) GetNetworks() ([]SNetwork, error) {
   321  	if len(self.networks) > 0 {
   322  		return self.networks, nil
   323  	}
   324  	self.networks = []SNetwork{}
   325  	resp, err := self.get("networks")
   326  	if err != nil {
   327  		return nil, err
   328  	}
   329  	return self.networks, resp.Unmarshal(&self.networks)
   330  }
   331  
   332  func (self *SRemoteFileClient) GetDisks() ([]SDisk, error) {
   333  	if len(self.disks) > 0 {
   334  		return self.disks, nil
   335  	}
   336  	self.disks = []SDisk{}
   337  	resp, err := self.get("disks")
   338  	if err != nil {
   339  		return nil, err
   340  	}
   341  	return self.disks, resp.Unmarshal(&self.disks)
   342  }
   343  
   344  func (self *SRemoteFileClient) GetProjects() ([]SProject, error) {
   345  	if len(self.projects) > 0 {
   346  		return self.projects, nil
   347  	}
   348  	resp, err := self.get("projects")
   349  	if err != nil {
   350  		return nil, err
   351  	}
   352  	self.projects = []SProject{}
   353  	return self.projects, resp.Unmarshal(&self.projects)
   354  }
   355  
   356  func (self *SRemoteFileClient) GetIProjects() ([]cloudprovider.ICloudProject, error) {
   357  	projects, err := self.GetProjects()
   358  	if err != nil {
   359  		return nil, err
   360  	}
   361  	ret := []cloudprovider.ICloudProject{}
   362  	for i := range projects {
   363  		ret = append(ret, &projects[i])
   364  	}
   365  	return ret, nil
   366  }
   367  
   368  func (self *SRemoteFileClient) GetCapabilities() []string {
   369  	caps := []string{
   370  		cloudprovider.CLOUD_CAPABILITY_PROJECT,
   371  		cloudprovider.CLOUD_CAPABILITY_COMPUTE,
   372  		cloudprovider.CLOUD_CAPABILITY_NETWORK,
   373  		cloudprovider.CLOUD_CAPABILITY_EIP,
   374  		cloudprovider.CLOUD_CAPABILITY_LOADBALANCER,
   375  		cloudprovider.CLOUD_CAPABILITY_QUOTA + cloudprovider.READ_ONLY_SUFFIX,
   376  		cloudprovider.CLOUD_CAPABILITY_OBJECTSTORE,
   377  		cloudprovider.CLOUD_CAPABILITY_RDS,
   378  		cloudprovider.CLOUD_CAPABILITY_CACHE,
   379  		cloudprovider.CLOUD_CAPABILITY_MISC,
   380  	}
   381  	return caps
   382  }