github.com/niedbalski/juju@v0.0.0-20190215020005-8ff100488e47/apiserver/facades/client/cloud/instance_information.go (about) 1 // Copyright 2016 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package cloud 5 6 import ( 7 "github.com/juju/errors" 8 "gopkg.in/juju/names.v2" 9 10 "github.com/juju/juju/apiserver/common" 11 "github.com/juju/juju/apiserver/params" 12 "github.com/juju/juju/core/constraints" 13 "github.com/juju/juju/environs" 14 "github.com/juju/juju/state/stateenvirons" 15 ) 16 17 // EnvironConfigGetter implements environs.EnvironConfigGetter 18 // in terms of a *state.State. 19 type cloudEnvironConfigGetter struct { 20 Backend 21 region string 22 } 23 24 // CloudSpec implements environs.EnvironConfigGetter. 25 func (g cloudEnvironConfigGetter) CloudSpec() (environs.CloudSpec, error) { 26 model, err := g.Model() 27 if err != nil { 28 return environs.CloudSpec{}, errors.Trace(err) 29 } 30 cloudName := model.Cloud() 31 regionName := g.region 32 credentialTag, _ := model.CloudCredential() 33 return stateenvirons.CloudSpec(g.Backend, cloudName, regionName, credentialTag) 34 } 35 36 // InstanceTypes returns instance type information for the cloud and region 37 // in which the current model is deployed. 38 func (api *CloudAPI) InstanceTypes(cons params.CloudInstanceTypesConstraints) (params.InstanceTypesResults, error) { 39 return instanceTypes(api, environs.GetEnviron, cons) 40 } 41 42 type environGetFunc func(st environs.EnvironConfigGetter, newEnviron environs.NewEnvironFunc) (environs.Environ, error) 43 44 func instanceTypes(api *CloudAPI, 45 environGet environGetFunc, 46 cons params.CloudInstanceTypesConstraints, 47 ) (params.InstanceTypesResults, error) { 48 m, err := api.ctlrBackend.Model() 49 if err != nil { 50 return params.InstanceTypesResults{}, errors.Trace(err) 51 } 52 53 result := make([]params.InstanceTypesResult, len(cons.Constraints)) 54 // TODO(perrito666) Cache the results to avoid excessive querying of the cloud. 55 // TODO(perrito666) Add Region<>Cloud validation. 56 for i, cons := range cons.Constraints { 57 value := constraints.Value{} 58 if cons.Constraints != nil { 59 value = *cons.Constraints 60 } 61 backend := cloudEnvironConfigGetter{ 62 Backend: api.backend, 63 region: cons.CloudRegion, 64 } 65 cloudTag, err := names.ParseCloudTag(cons.CloudTag) 66 if err != nil { 67 result[i] = params.InstanceTypesResult{Error: common.ServerError(err)} 68 continue 69 } 70 if m.Cloud() != cloudTag.Id() { 71 result[i] = params.InstanceTypesResult{Error: common.ServerError(errors.NotValidf("asking %s cloud information to %s cloud", cloudTag.Id(), m.Cloud()))} 72 continue 73 } 74 75 env, err := environGet(backend, environs.New) 76 if err != nil { 77 return params.InstanceTypesResults{}, errors.Trace(err) 78 } 79 80 itCons := common.NewInstanceTypeConstraints( 81 env, 82 api.callContext, 83 value, 84 ) 85 it, err := common.InstanceTypes(itCons) 86 if err != nil { 87 result[i] = params.InstanceTypesResult{Error: common.ServerError(err)} 88 continue 89 } 90 result[i] = it 91 } 92 93 return params.InstanceTypesResults{Results: result}, nil 94 }