Skip to content

Commit

Permalink
Merge pull request #13963 from manadart/develop-into-3.0-dqlite
Browse files Browse the repository at this point in the history
Merge develop into 3.0-dqlite
  • Loading branch information
manadart committed Apr 21, 2022
2 parents 5449603 + 3a2d359 commit 741baca
Show file tree
Hide file tree
Showing 118 changed files with 1,145 additions and 968 deletions.
19 changes: 0 additions & 19 deletions api/agent/uniter/unit.go
Original file line number Diff line number Diff line change
Expand Up @@ -870,25 +870,6 @@ func (u *Unit) NetworkInfo(bindings []string, relationId *int) (map[string]param
return results.Results, nil
}

// UpdateNetworkInfo updates the network settings for the unit's bound
// endpoints.
func (u *Unit) UpdateNetworkInfo() error {
args := params.Entities{
Entities: []params.Entity{
{
Tag: u.tag.String(),
},
},
}

var results params.ErrorResults
err := u.st.facade.FacadeCall("UpdateNetworkInfo", args, &results)
if err != nil {
return errors.Trace(err)
}
return results.OneError()
}

// State returns the state persisted by the charm running in this unit
// and the state internal to the uniter for this unit.
func (u *Unit) State() (params.UnitStateResult, error) {
Expand Down
19 changes: 5 additions & 14 deletions api/apiclient.go
Original file line number Diff line number Diff line change
Expand Up @@ -285,7 +285,7 @@ func Open(info *Info, opts DialOpts) (Connection, error) {

go (&monitor{
clock: opts.Clock,
ping: st.Ping,
ping: st.ping,
pingPeriod: PingPeriod,
pingTimeout: pingTimeout,
closed: st.closed,
Expand Down Expand Up @@ -463,7 +463,7 @@ func (st *state) connectStream(path string, attrs url.Values, extraHeaders http.
}
}

connection, err := websocketDial(dialer, target.String(), requestHeader)
connection, err := WebsocketDial(dialer, target.String(), requestHeader)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -568,8 +568,8 @@ func apiURL(addr, model string) *url.URL {
}
}

// Ping implements api.Connection.
func (s *state) Ping() error {
// ping implements calls the Pinger.ping facade.
func (s *state) ping() error {
return s.APICall("Pinger", s.pingerFacadeVersion, "", "Ping", nil, nil)
}

Expand Down Expand Up @@ -1318,7 +1318,7 @@ func (s *state) IsBroken() bool {
return true
default:
}
if err := s.Ping(); err != nil {
if err := s.ping(); err != nil {
logger.Debugf("connection ping failed: %v", err)
return true
}
Expand Down Expand Up @@ -1382,15 +1382,6 @@ func (s *state) PublicDNSName() string {
return s.publicDNSName
}

// AllFacadeVersions returns what versions we know about for all facades
func (s *state) AllFacadeVersions() map[string][]int {
facades := make(map[string][]int, len(s.facadeVersions))
for name, versions := range s.facadeVersions {
facades[name] = append([]int{}, versions...)
}
return facades
}

// BestFacadeVersion compares the versions of facades that we know about, and
// the versions available from the server, and reports back what version is the
// 'best available' to use.
Expand Down
25 changes: 1 addition & 24 deletions api/apiclient_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -321,7 +321,7 @@ func (s *apiclientSuite) TestOpenHonorsModelTag(c *gc.C) {
}

func (s *apiclientSuite) TestServerRoot(c *gc.C) {
url := api.ServerRoot(api.NewClient(s.APIState))
url := api.ServerRoot(s.APIState)
c.Assert(url, gc.Matches, "https://localhost:[0-9]+")
}

Expand Down Expand Up @@ -1127,29 +1127,6 @@ func (s *apiclientSuite) TestAPICallError(c *gc.C) {
c.Check(clock.waits, gc.HasLen, 0)
}

func (s *apiclientSuite) TestPing(c *gc.C) {
clock := &fakeClock{}
rpcConn := newRPCConnection()
conn := api.NewTestingState(api.TestingStateParams{
RPCConnection: rpcConn,
Clock: clock,
})
err := conn.Ping()
c.Assert(err, jc.ErrorIsNil)
rpcConn.stub.CheckCalls(c, []testing.StubCall{{
"Pinger.Ping", []interface{}{0, nil},
}})
}

func (s *apiclientSuite) TestPingBroken(c *gc.C) {
conn := api.NewTestingState(api.TestingStateParams{
RPCConnection: newRPCConnection(errors.New("no biscuit")),
Clock: &fakeClock{},
})
err := conn.Ping()
c.Assert(err, gc.ErrorMatches, "no biscuit")
}

func (s *apiclientSuite) TestIsBrokenOk(c *gc.C) {
conn := api.NewTestingState(api.TestingStateParams{
RPCConnection: newRPCConnection(),
Expand Down
90 changes: 7 additions & 83 deletions api/client.go → api/client/client/client.go
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
// Copyright 2013, 2014 Canonical Ltd.
// Licensed under the AGPLv3, see LICENCE file for details.

package api
package client

import (
"archive/zip"
"context"
"encoding/json"
"fmt"
"io"
"io/ioutil"
Expand All @@ -15,16 +14,16 @@ import (
"os"
"strconv"
"strings"
"time"

"github.com/gorilla/websocket"
"github.com/juju/charm/v9"
csparams "github.com/juju/charmrepo/v7/csclient/params"
"github.com/juju/errors"
"github.com/juju/names/v4"
"github.com/juju/version/v2"
"github.com/lxc/lxd/shared/logger"
"gopkg.in/macaroon.v2"

"github.com/juju/juju/api"
"github.com/juju/juju/api/base"
"github.com/juju/juju/api/common"
"github.com/juju/juju/core/constraints"
Expand All @@ -38,20 +37,16 @@ import (
jujuversion "github.com/juju/juju/version"
)

// websocketTimeout is how long we'll wait for a WriteJSON call before
// timing it out.
const websocketTimeout = 30 * time.Second

// Client represents the client-accessible part of the state.
type Client struct {
base.ClientFacade
facade base.FacadeCaller
conn Connection
conn api.Connection
}

// NewClient returns an object that can be used to access client-specific
// functionality.
func NewClient(c Connection) *Client {
func NewClient(c api.Connection) *Client {
frontend, backend := base.NewClientFacade(c, "Client")
return &Client{ClientFacade: frontend, facade: backend, conn: c}
}
Expand Down Expand Up @@ -270,12 +265,12 @@ func (c *Client) ModelUserInfo() ([]params.ModelUserInfo, error) {

// WatchAll returns an AllWatcher, from which you can request the Next
// collection of Deltas.
func (c *Client) WatchAll() (*AllWatcher, error) {
func (c *Client) WatchAll() (*api.AllWatcher, error) {
var info params.AllWatcherId
if err := c.facade.FacadeCall("WatchAll", nil, &info); err != nil {
return nil, err
}
return NewAllWatcher(c.conn, &info.AllWatcherId), nil
return api.NewAllWatcher(c.conn, &info.AllWatcherId), nil
}

// Close closes the Client's underlying State connection
Expand Down Expand Up @@ -627,77 +622,6 @@ func (c *Client) AgentVersion() (version.Number, error) {
return result.Version, nil
}

// websocketDial is called instead of dialer.Dial so we can override it in
// tests.
var websocketDial = websocketDialWithErrors

// WebsocketDialer is something that can make a websocket connection. Enables
// testing the error unpacking in websocketDialWithErrors.
type WebsocketDialer interface {
Dial(string, http.Header) (*websocket.Conn, *http.Response, error)
}

// websocketDialWithErrors dials the websocket and extracts any error
// from the response if there's a handshake error setting up the
// socket. Any other errors are returned normally.
func websocketDialWithErrors(dialer WebsocketDialer, urlStr string, requestHeader http.Header) (base.Stream, error) {
c, resp, err := dialer.Dial(urlStr, requestHeader)
if err != nil {
if err == websocket.ErrBadHandshake {
// If ErrBadHandshake is returned, a non-nil response
// is returned so the client can react to auth errors
// (for example).
//
// The problem here is that there is a response, but the response
// body is truncated to 1024 bytes for debugging information, not
// for a true response. While this may work for small bodies, it
// isn't guaranteed to work for all messages.
defer resp.Body.Close()
body, readErr := ioutil.ReadAll(resp.Body)
if readErr != nil {
return nil, err
}
if resp.Header.Get("Content-Type") == "application/json" {
var result params.ErrorResult
jsonErr := json.Unmarshal(body, &result)
if jsonErr != nil {
return nil, errors.Annotate(jsonErr, "reading error response")
}
return nil, result.Error
}

err = errors.Errorf(
"%s (%s)",
strings.TrimSpace(string(body)),
http.StatusText(resp.StatusCode),
)
}
return nil, err
}
result := DeadlineStream{Conn: c, Timeout: websocketTimeout}
return &result, nil
}

// DeadlineStream wraps a websocket connection and applies a write
// deadline to each WriteJSON call.
type DeadlineStream struct {
*websocket.Conn

Timeout time.Duration
}

// WriteJSON is part of base.Stream.
func (s *DeadlineStream) WriteJSON(v interface{}) error {
// This uses a real clock rather than trying to use a clock passed
// in because the websocket will use a real clock to determine
// whether the deadline has passed anyway.
deadline := time.Now().Add(s.Timeout)
if err := s.Conn.SetWriteDeadline(deadline); err != nil {
return errors.Annotate(err, "setting write deadline")
}
return errors.Trace(s.Conn.WriteJSON(v))
}

// WatchDebugLog returns a channel of structured Log Messages. Only log entries
// that match the filtering specified in the DebugLogParams are returned.
func (c *Client) WatchDebugLog(args common.DebugLogParams) (<-chan common.LogMessage, error) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// Copyright 2015 Canonical Ltd.
// Licensed under the AGPLv3, see LICENCE file for details.

package api_test
package client_test

import (
"fmt"
Expand All @@ -11,7 +11,7 @@ import (
jc "github.com/juju/testing/checkers"
gc "gopkg.in/check.v1"

"github.com/juju/juju/api"
"github.com/juju/juju/api/client/client"
apitesting "github.com/juju/juju/api/testing"
"github.com/juju/juju/core/permission"
"github.com/juju/juju/testcharms"
Expand All @@ -26,13 +26,13 @@ type clientMacaroonSuite struct {
apitesting.MacaroonSuite
}

func (s *clientMacaroonSuite) createTestClient(c *gc.C) *api.Client {
func (s *clientMacaroonSuite) createTestClient(c *gc.C) *client.Client {
username := "testuser@somewhere"
s.AddModelUser(c, username)
s.AddControllerUser(c, username, permission.LoginAccess)
cookieJar := apitesting.NewClearableCookieJar()
s.DischargerLogin = func() string { return username }
client := api.NewClient(s.OpenAPI(c, nil, cookieJar))
client := client.NewClient(s.OpenAPI(c, nil, cookieJar))

// Even though we've logged into the API, we want
// the tests below to exercise the discharging logic
Expand Down
Loading

0 comments on commit 741baca

Please sign in to comment.