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  }