github.com/juju/juju@v0.0.0-20240430160146-1752b71fcf00/api/common/cloudspec/cloudspec.go (about) 1 // Copyright 2016 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package cloudspec 5 6 import ( 7 "github.com/juju/errors" 8 "github.com/juju/names/v5" 9 10 "github.com/juju/juju/api/base" 11 apiwatcher "github.com/juju/juju/api/watcher" 12 "github.com/juju/juju/cloud" 13 "github.com/juju/juju/core/watcher" 14 environscloudspec "github.com/juju/juju/environs/cloudspec" 15 "github.com/juju/juju/rpc/params" 16 ) 17 18 // CloudSpecAPI provides common client-side API functions 19 // to call into apiserver/common/environscloudspec.CloudSpec. 20 type CloudSpecAPI struct { 21 facade base.FacadeCaller 22 modelTag names.ModelTag 23 } 24 25 // NewCloudSpecAPI creates a CloudSpecAPI using the provided 26 // FacadeCaller. 27 func NewCloudSpecAPI(facade base.FacadeCaller, modelTag names.ModelTag) *CloudSpecAPI { 28 return &CloudSpecAPI{facade, modelTag} 29 } 30 31 // WatchCloudSpecChanges returns a NotifyWatcher waiting for the 32 // model's cloud to change. 33 func (api *CloudSpecAPI) WatchCloudSpecChanges() (watcher.NotifyWatcher, error) { 34 var results params.NotifyWatchResults 35 args := params.Entities{Entities: []params.Entity{{api.modelTag.String()}}} 36 err := api.facade.FacadeCall("WatchCloudSpecsChanges", args, &results) 37 if err != nil { 38 return nil, err 39 } 40 if n := len(results.Results); n != 1 { 41 return nil, errors.Errorf("expected 1 result, got %d", n) 42 } 43 result := results.Results[0] 44 if result.Error != nil { 45 return nil, errors.Annotate(result.Error, "API request failed") 46 } 47 return apiwatcher.NewNotifyWatcher(api.facade.RawAPICaller(), result), nil 48 } 49 50 // CloudSpec returns the cloud specification for the model associated 51 // with the API facade. 52 func (api *CloudSpecAPI) CloudSpec() (environscloudspec.CloudSpec, error) { 53 var results params.CloudSpecResults 54 args := params.Entities{Entities: []params.Entity{{api.modelTag.String()}}} 55 err := api.facade.FacadeCall("CloudSpec", args, &results) 56 if err != nil { 57 return environscloudspec.CloudSpec{}, err 58 } 59 if n := len(results.Results); n != 1 { 60 return environscloudspec.CloudSpec{}, errors.Errorf("expected 1 result, got %d", n) 61 } 62 result := results.Results[0] 63 if result.Error != nil { 64 return environscloudspec.CloudSpec{}, errors.Annotate(result.Error, "API request failed") 65 } 66 return api.MakeCloudSpec(result.Result) 67 } 68 69 // MakeCloudSpec creates an environscloudspec.CloudSpec from a params.CloudSpec 70 // that has been returned from the apiserver. 71 func (api *CloudSpecAPI) MakeCloudSpec(pSpec *params.CloudSpec) (environscloudspec.CloudSpec, error) { 72 if pSpec == nil { 73 return environscloudspec.CloudSpec{}, errors.NotValidf("nil value") 74 } 75 var credential *cloud.Credential 76 if pSpec.Credential != nil { 77 credentialValue := cloud.NewCredential( 78 cloud.AuthType(pSpec.Credential.AuthType), 79 pSpec.Credential.Attributes, 80 ) 81 credential = &credentialValue 82 } 83 spec := environscloudspec.CloudSpec{ 84 Type: pSpec.Type, 85 Name: pSpec.Name, 86 Region: pSpec.Region, 87 Endpoint: pSpec.Endpoint, 88 IdentityEndpoint: pSpec.IdentityEndpoint, 89 StorageEndpoint: pSpec.StorageEndpoint, 90 CACertificates: pSpec.CACertificates, 91 SkipTLSVerify: pSpec.SkipTLSVerify, 92 Credential: credential, 93 IsControllerCloud: pSpec.IsControllerCloud, 94 } 95 if err := spec.Validate(); err != nil { 96 return environscloudspec.CloudSpec{}, errors.Annotate(err, "validating CloudSpec") 97 } 98 return spec, nil 99 }