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 }