github.com/wallyworld/juju@v0.0.0-20161013125918-6cf1bc9d917a/api/interface.go (about) 1 // Copyright 2012-2015 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package api 5 6 import ( 7 "net/url" 8 "time" 9 10 "github.com/juju/errors" 11 "github.com/juju/version" 12 "gopkg.in/juju/names.v2" 13 "gopkg.in/macaroon-bakery.v1/httpbakery" 14 "gopkg.in/macaroon.v1" 15 16 "github.com/juju/juju/api/base" 17 "github.com/juju/juju/api/charmrevisionupdater" 18 "github.com/juju/juju/api/cleaner" 19 "github.com/juju/juju/api/discoverspaces" 20 "github.com/juju/juju/api/imagemetadata" 21 "github.com/juju/juju/api/instancepoller" 22 "github.com/juju/juju/api/reboot" 23 "github.com/juju/juju/api/unitassigner" 24 "github.com/juju/juju/api/uniter" 25 "github.com/juju/juju/api/upgrader" 26 "github.com/juju/juju/network" 27 "github.com/juju/utils/set" 28 ) 29 30 // Info encapsulates information about a server holding juju state and 31 // can be used to make a connection to it. 32 type Info struct { 33 34 // This block of fields is sufficient to connect: 35 36 // Addrs holds the addresses of the controllers. 37 Addrs []string 38 39 // CACert holds the CA certificate that will be used 40 // to validate the controller's certificate, in PEM format. 41 // If this is empty, the standard system root certificates 42 // will be used. 43 CACert string 44 45 // ModelTag holds the model tag for the model we are 46 // trying to connect to. If this is empty, a controller-only 47 // login will be made. 48 ModelTag names.ModelTag 49 50 // ...but this block of fields is all about the authentication mechanism 51 // to use after connecting -- if any -- and should probably be extracted. 52 53 // SkipLogin, if true, skips the Login call on connection. It is an 54 // error to set Tag, Password, or Macaroons if SkipLogin is true. 55 SkipLogin bool `yaml:"-"` 56 57 // Tag holds the name of the entity that is connecting. 58 // If this is nil, and the password is empty, macaroon authentication 59 // will be used to log in unless SkipLogin is true. 60 Tag names.Tag 61 62 // Password holds the password for the administrator or connecting entity. 63 Password string 64 65 // Macaroons holds a slice of macaroon.Slice that may be used to 66 // authenticate with the API server. 67 Macaroons []macaroon.Slice `yaml:",omitempty"` 68 69 // Nonce holds the nonce used when provisioning the machine. Used 70 // only by the machine agent. 71 Nonce string `yaml:",omitempty"` 72 } 73 74 // Ports returns the unique ports for the api addresses. 75 func (info *Info) Ports() []int { 76 ports := set.NewInts() 77 hostPorts, err := network.ParseHostPorts(info.Addrs...) 78 if err != nil { 79 // Addresses have already been validated. 80 panic(err) 81 } 82 for _, hp := range hostPorts { 83 ports.Add(hp.Port) 84 } 85 return ports.Values() 86 } 87 88 // Validate validates the API info. 89 func (info *Info) Validate() error { 90 if len(info.Addrs) == 0 { 91 return errors.NotValidf("missing addresses") 92 } 93 if _, err := network.ParseHostPorts(info.Addrs...); err != nil { 94 return errors.NotValidf("host addresses: %v", err) 95 } 96 if info.SkipLogin { 97 if info.Tag != nil { 98 return errors.NotValidf("specifying Tag and SkipLogin") 99 } 100 if info.Password != "" { 101 return errors.NotValidf("specifying Password and SkipLogin") 102 } 103 if len(info.Macaroons) > 0 { 104 return errors.NotValidf("specifying Macaroons and SkipLogin") 105 } 106 } 107 return nil 108 } 109 110 // DialOpts holds configuration parameters that control the 111 // Dialing behavior when connecting to a controller. 112 type DialOpts struct { 113 // DialAddressInterval is the amount of time to wait 114 // before starting to dial another address. 115 DialAddressInterval time.Duration 116 117 // Timeout is the amount of time to wait contacting 118 // a controller. 119 Timeout time.Duration 120 121 // RetryDelay is the amount of time to wait between 122 // unsuccessful connection attempts. 123 RetryDelay time.Duration 124 125 // BakeryClient is the httpbakery Client, which 126 // is used to do the macaroon-based authorization. 127 // This and the *http.Client inside it are copied 128 // by Open, and any RoundTripper field 129 // the HTTP client is ignored. 130 BakeryClient *httpbakery.Client 131 132 // InsecureSkipVerify skips TLS certificate verification 133 // when connecting to the controller. This should only 134 // be used in tests, or when verification cannot be 135 // performed and the communication need not be secure. 136 InsecureSkipVerify bool 137 } 138 139 // DefaultDialOpts returns a DialOpts representing the default 140 // parameters for contacting a controller. 141 func DefaultDialOpts() DialOpts { 142 return DialOpts{ 143 DialAddressInterval: 50 * time.Millisecond, 144 Timeout: 10 * time.Minute, 145 RetryDelay: 2 * time.Second, 146 } 147 } 148 149 // OpenFunc is the usual form of a function that opens an API connection. 150 type OpenFunc func(*Info, DialOpts) (Connection, error) 151 152 // Connection exists purely to make api-opening funcs mockable. It's just a 153 // dumb copy of all the methods on api.state; we can and should be extracting 154 // smaller and more relevant interfaces (and dropping some of them too). 155 156 // Connection represents a connection to a Juju API server. 157 type Connection interface { 158 159 // This first block of methods is pretty close to a sane Connection interface. 160 Close() error 161 Addr() string 162 APIHostPorts() [][]network.HostPort 163 164 // Broken returns a channel which will be closed if the connection 165 // is detected to be broken, either because the underlying 166 // connection has closed or because API pings have failed. 167 Broken() <-chan struct{} 168 169 // IsBroken returns whether the connection is broken. It checks 170 // the Broken channel and if that is open, attempts a connection 171 // ping. 172 IsBroken() bool 173 174 // These are a bit off -- ServerVersion is apparently not known until after 175 // Login()? Maybe evidence of need for a separate AuthenticatedConnection..? 176 Login(name names.Tag, password, nonce string, ms []macaroon.Slice) error 177 ServerVersion() (version.Number, bool) 178 179 // APICaller provides the facility to make API calls directly. 180 // This should not be used outside the api/* packages or tests. 181 base.APICaller 182 183 // ControllerTag returns the tag of the controller. 184 // This could be defined on base.APICaller. 185 ControllerTag() names.ControllerTag 186 187 // All the rest are strange and questionable and deserve extra attention 188 // and/or discussion. 189 190 // Ping makes an API request which checks if the connection is 191 // still functioning. 192 // NOTE: This method is deprecated. Please use IsBroken or Broken instead. 193 Ping() error 194 195 // I think this is actually dead code. It's tested, at least, so I'm 196 // keeping it for now, but it's not apparently used anywhere else. 197 AllFacadeVersions() map[string][]int 198 199 // AuthTag returns the tag of the authorized user of the state API 200 // connection. 201 AuthTag() names.Tag 202 203 // ModelAccess returns the access level of authorized user to the model. 204 ModelAccess() string 205 206 // ControllerAccess returns the access level of authorized user to the controller. 207 ControllerAccess() string 208 209 // CookieURL returns the URL that HTTP cookies for the API will be 210 // associated with. 211 CookieURL() *url.URL 212 213 // These methods expose a bunch of worker-specific facades, and basically 214 // just should not exist; but removing them is too noisy for a single CL. 215 // Client in particular is intimately coupled with State -- and the others 216 // will be easy to remove, but until we're using them via manifolds it's 217 // prohibitively ugly to do so. 218 Client() *Client 219 Uniter() (*uniter.State, error) 220 Upgrader() *upgrader.State 221 Reboot() (reboot.State, error) 222 DiscoverSpaces() *discoverspaces.API 223 InstancePoller() *instancepoller.API 224 CharmRevisionUpdater() *charmrevisionupdater.State 225 Cleaner() *cleaner.API 226 MetadataUpdater() *imagemetadata.Client 227 UnitAssigner() unitassigner.API 228 }