github.com/juju/juju@v0.0.0-20240430160146-1752b71fcf00/doc/third-party-go-clients.md (about) 1 # Third party Go clients 2 3 This describes an approach to allow third party Go codebases to drive Juju. At 4 a high level it works like this. 5 6 1. Create a connector instance, telling it how to connect to a Juju controller 7 and how to provide authentication credentials. 8 2. Use this connector instance to obtain a connection instance. 9 3. Get a facade client from the connection. 10 4. Use the facade client to make one or more requests. 11 12 ## The `Connector` interface 13 14 The `github.com/juju/juju/api/connector` package defines a `Connector` 15 interface. 16 17 ```golang 18 type Connector interface { 19 Connect(...api.DialOption) (api.Connection, error) 20 } 21 ``` 22 23 Its only purpose is to create instances of `api.Connection` that can later be 24 used to talk to a given Juju controller with a given set of credentials. There 25 are currently two ways to obtain a `Connector` instance. 26 27 ### `SimpleConnector` 28 29 If one knows the how to contact a controller, and some juju user credentials 30 (e.g. username and password) it is possible to obtain a connector like this. 31 32 ```golang 33 import "github.com/juju/juju/api/connector" 34 ``` 35 ```golang 36 connr, err := connector.NewSimple(connector.SimpleConfig{ 37 ControllerAddresses: []string{"10.225.205.241:17070"}, 38 CaCert: "...", 39 Username: "jujuuser", 40 Password: "password1", 41 }) 42 ``` 43 44 There can be an error if the config is not valid (e.g. no controller address 45 specified). 46 47 ### `ClientStoreConnector` 48 49 If a client store is available on the filesystem, it is possible to use it to 50 configure the connector. 51 52 ```golang 53 import "github.com/juju/juju/api/connector" 54 ``` 55 ```golang 56 connr, err := connector.NewClientStore(connector.ClientStoreConfig{ 57 ControllerName: "overlord", 58 }) 59 ``` 60 61 The above will try to find a client store in the default location. It is also 62 possible to pass in a custom value (see `clientstoreconnector.go` for details). 63 64 ## Making requests 65 66 Once we have a connector, it's easy to make requests. 67 68 ```golang 69 import ( 70 "encoding/json" 71 "github.com/juju/juju/api/connector" 72 "github.com/juju/juju/api/client/client" 73 ) 74 ``` 75 ```golang 76 // Get a connection 77 conn, err := connr.Connect() 78 if err != nil { 79 log.Fatalf("Error opening connection: %s", err) 80 } 81 defer conn.Close() 82 83 // Get a Client facade client 84 client := apiclient.NewClient(conn) 85 86 // Call the Status endpoint of the client facade 87 status, err := client.Status(nil) 88 if err != nil { 89 log.Fatalf("Error requesting status: %s", err) 90 } 91 92 // Print to stdout. 93 b, err := json.MarshalIndent(status, "", " ") 94 if err != nil { 95 log.Fatalf("Error marshalling response: %s", err) 96 } 97 fmt.Printf("%s\n", b) 98 ``` 99 100 ## Points to address 101 102 - When to reuse a connection, when to create a new one? 103 - How to find the useful endpoints? 104