github.com/juju/juju@v0.0.0-20240430160146-1752b71fcf00/api/connector/simpleconnector.go (about) 1 // Copyright 2022 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package connector 5 6 import ( 7 "github.com/juju/names/v5" 8 "gopkg.in/macaroon.v2" 9 10 "github.com/juju/juju/api" 11 ) 12 13 // SimpleConfig aims to provide the same API surface as pilot juju for 14 // obtaining an api connection. 15 type SimpleConfig struct { 16 17 // Addresses of controllers (at least one required, more than one for HA). 18 ControllerAddresses []string 19 20 // I don't know if that's required 21 CACert string 22 23 // UUID of model to connect to (optional) 24 ModelUUID string 25 26 // Either Username/Password or Macaroons is required to get authentication. 27 Username string 28 Password string 29 Macaroons []macaroon.Slice 30 31 // ClientID holds the client id part of client credentials used for authentication. 32 ClientID string 33 // ClientSecret holds the client secret part of client 34 // credentials used for authentication. 35 ClientSecret string 36 } 37 38 // A SimpleConnector can provide connections from a simple set of options. 39 type SimpleConnector struct { 40 info api.Info 41 defaultDialOpts api.DialOpts 42 } 43 44 var _ Connector = (*SimpleConnector)(nil) 45 46 // NewSimple returns an instance of *SimpleConnector configured to 47 // connect according to the specified options. If some options are invalid an 48 // error is returned. 49 func NewSimple(opts SimpleConfig, dialOptions ...api.DialOption) (*SimpleConnector, error) { 50 info := api.Info{ 51 Addrs: opts.ControllerAddresses, 52 CACert: opts.CACert, 53 ModelTag: names.NewModelTag(opts.ModelUUID), 54 55 Tag: names.NewUserTag(opts.Username), 56 Password: opts.Password, 57 Macaroons: opts.Macaroons, 58 } 59 if err := info.Validate(); err != nil { 60 return nil, err 61 } 62 63 dialOpts := api.DefaultDialOpts() 64 if opts.ClientID != "" && opts.ClientSecret != "" { 65 dialOpts.LoginProvider = api.NewClientCredentialsLoginProvider( 66 opts.ClientID, 67 opts.ClientSecret, 68 ) 69 } 70 71 conn := &SimpleConnector{ 72 info: info, 73 defaultDialOpts: dialOpts, 74 } 75 76 for _, f := range dialOptions { 77 f(&conn.defaultDialOpts) 78 } 79 return conn, nil 80 } 81 82 // Connect returns a Connection according to c's configuration. 83 func (c *SimpleConnector) Connect(dialOptions ...api.DialOption) (api.Connection, error) { 84 opts := c.defaultDialOpts 85 for _, f := range dialOptions { 86 f(&opts) 87 } 88 return api.Open(&c.info, c.defaultDialOpts) 89 }