github.com/axw/juju@v0.0.0-20161005053422-4bd6544d08d4/api/cloud/cloud.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 "gopkg.in/juju/names.v2" 8 9 "github.com/juju/errors" 10 "github.com/juju/juju/api/base" 11 "github.com/juju/juju/apiserver/params" 12 jujucloud "github.com/juju/juju/cloud" 13 ) 14 15 // Client provides methods that the Juju client command uses to interact 16 // with models stored in the Juju Server. 17 type Client struct { 18 base.ClientFacade 19 facade base.FacadeCaller 20 } 21 22 // NewClient creates a new `Client` based on an existing authenticated API 23 // connection. 24 func NewClient(st base.APICallCloser) *Client { 25 frontend, backend := base.NewClientFacade(st, "Cloud") 26 return &Client{ClientFacade: frontend, facade: backend} 27 } 28 29 // Clouds returns the details of all clouds supported by the controller. 30 func (c *Client) Clouds() (map[names.CloudTag]jujucloud.Cloud, error) { 31 var result params.CloudsResult 32 if err := c.facade.FacadeCall("Clouds", nil, &result); err != nil { 33 return nil, errors.Trace(err) 34 } 35 clouds := make(map[names.CloudTag]jujucloud.Cloud) 36 for tagString, cloud := range result.Clouds { 37 tag, err := names.ParseCloudTag(tagString) 38 if err != nil { 39 return nil, errors.Trace(err) 40 } 41 clouds[tag] = cloudFromParams(cloud) 42 } 43 return clouds, nil 44 } 45 46 // Cloud returns the details of the cloud with the given tag. 47 func (c *Client) Cloud(tag names.CloudTag) (jujucloud.Cloud, error) { 48 var results params.CloudResults 49 args := params.Entities{[]params.Entity{{tag.String()}}} 50 if err := c.facade.FacadeCall("Cloud", args, &results); err != nil { 51 return jujucloud.Cloud{}, errors.Trace(err) 52 } 53 if len(results.Results) != 1 { 54 return jujucloud.Cloud{}, errors.Errorf("expected 1 result, got %d", len(results.Results)) 55 } 56 if results.Results[0].Error != nil { 57 return jujucloud.Cloud{}, results.Results[0].Error 58 } 59 return cloudFromParams(*results.Results[0].Cloud), nil 60 } 61 62 func cloudFromParams(p params.Cloud) jujucloud.Cloud { 63 authTypes := make([]jujucloud.AuthType, len(p.AuthTypes)) 64 for i, authType := range p.AuthTypes { 65 authTypes[i] = jujucloud.AuthType(authType) 66 } 67 regions := make([]jujucloud.Region, len(p.Regions)) 68 for i, region := range p.Regions { 69 regions[i] = jujucloud.Region{ 70 Name: region.Name, 71 Endpoint: region.Endpoint, 72 IdentityEndpoint: region.IdentityEndpoint, 73 StorageEndpoint: region.StorageEndpoint, 74 } 75 } 76 return jujucloud.Cloud{ 77 Type: p.Type, 78 AuthTypes: authTypes, 79 Endpoint: p.Endpoint, 80 IdentityEndpoint: p.IdentityEndpoint, 81 StorageEndpoint: p.StorageEndpoint, 82 Regions: regions, 83 } 84 } 85 86 // DefaultCloud returns the tag of the cloud that models will be 87 // created in by default. 88 func (c *Client) DefaultCloud() (names.CloudTag, error) { 89 var result params.StringResult 90 if err := c.facade.FacadeCall("DefaultCloud", nil, &result); err != nil { 91 return names.CloudTag{}, errors.Trace(err) 92 } 93 if result.Error != nil { 94 return names.CloudTag{}, result.Error 95 } 96 cloudTag, err := names.ParseCloudTag(result.Result) 97 if err != nil { 98 return names.CloudTag{}, errors.Trace(err) 99 } 100 return cloudTag, nil 101 } 102 103 // UserCredentials returns the tags for cloud credentials available to a user for 104 // use with a specific cloud. 105 func (c *Client) UserCredentials(user names.UserTag, cloud names.CloudTag) ([]names.CloudCredentialTag, error) { 106 var results params.StringsResults 107 args := params.UserClouds{[]params.UserCloud{ 108 {UserTag: user.String(), CloudTag: cloud.String()}, 109 }} 110 if err := c.facade.FacadeCall("UserCredentials", args, &results); err != nil { 111 return nil, errors.Trace(err) 112 } 113 if len(results.Results) != 1 { 114 return nil, errors.Errorf("expected 1 result, got %d", len(results.Results)) 115 } 116 if results.Results[0].Error != nil { 117 return nil, results.Results[0].Error 118 } 119 tags := make([]names.CloudCredentialTag, len(results.Results[0].Result)) 120 for i, s := range results.Results[0].Result { 121 tag, err := names.ParseCloudCredentialTag(s) 122 if err != nil { 123 return nil, errors.Trace(err) 124 } 125 tags[i] = tag 126 } 127 return tags, nil 128 } 129 130 // UpdateCredential updates a cloud credentials. 131 func (c *Client) UpdateCredential(tag names.CloudCredentialTag, credential jujucloud.Credential) error { 132 var results params.ErrorResults 133 args := params.UpdateCloudCredentials{ 134 Credentials: []params.UpdateCloudCredential{{ 135 Tag: tag.String(), 136 Credential: params.CloudCredential{ 137 AuthType: string(credential.AuthType()), 138 Attributes: credential.Attributes(), 139 }, 140 }}, 141 } 142 if err := c.facade.FacadeCall("UpdateCredentials", args, &results); err != nil { 143 return errors.Trace(err) 144 } 145 return results.OneError() 146 } 147 148 // RevokeCredential revokes/deletes a cloud credential. 149 func (c *Client) RevokeCredential(tag names.CloudCredentialTag) error { 150 var results params.ErrorResults 151 args := params.Entities{ 152 Entities: []params.Entity{{ 153 Tag: tag.String(), 154 }}, 155 } 156 if err := c.facade.FacadeCall("RevokeCredentials", args, &results); err != nil { 157 return errors.Trace(err) 158 } 159 return results.OneError() 160 } 161 162 // Credentials return a slice of credential values for the specified tags. 163 // Secrets are excluded from the credential attributes. 164 func (c *Client) Credentials(tags ...names.CloudCredentialTag) ([]params.CloudCredentialResult, error) { 165 if len(tags) == 0 { 166 return []params.CloudCredentialResult{}, nil 167 } 168 var results params.CloudCredentialResults 169 args := params.Entities{ 170 Entities: make([]params.Entity, len(tags)), 171 } 172 for i, tag := range tags { 173 args.Entities[i].Tag = tag.String() 174 } 175 if err := c.facade.FacadeCall("Credential", args, &results); err != nil { 176 return nil, errors.Trace(err) 177 } 178 return results.Results, nil 179 }