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