Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

merge new-channels-model branch #71

Merged
14 changes: 14 additions & 0 deletions csclient/csclient.go
Expand Up @@ -40,6 +40,7 @@ type Client struct {
bclient httpClient
header http.Header
statsDisabled bool
channel params.Channel
}

// Params holds parameters for creating a new charm store client.
Expand Down Expand Up @@ -101,6 +102,14 @@ func (c *Client) DisableStats() {
c.statsDisabled = true
}

// WithChannel returns a new client whose requests are done using the
// given channel.
func (c *Client) WithChannel(channel params.Channel) *Client {
client := *c
client.channel = channel
return &client
}

// SetHTTPHeader sets custom HTTP headers that will be sent to the charm store
// on each request.
func (c *Client) SetHTTPHeader(header http.Header) {
Expand Down Expand Up @@ -661,6 +670,11 @@ func (c *Client) DoWithBody(req *http.Request, path string, body io.ReadSeeker)
if err != nil {
return nil, errgo.Mask(err)
}
if c.channel != params.NoChannel {
values := u.Query()
values.Set("channel", string(c.channel))
u.RawQuery = values.Encode()
}
req.URL = u

// Send the request.
Expand Down
55 changes: 43 additions & 12 deletions csclient/csclient_test.go
Expand Up @@ -298,22 +298,27 @@ func (s *suite) TestPutSuccess(c *gc.C) {
}

func (s *suite) TestPutWithResponseSuccess(c *gc.C) {
err := s.client.UploadCharmWithRevision(
charm.MustParseURL("~charmers/development/wily/wordpress-42"),
charmRepo.CharmDir("wordpress"),
42)
c.Assert(err, gc.IsNil)

publish := &params.PublishRequest{
Published: true,
// There are currently no endpoints that return a response
// on PUT, so we'll create a fake server just to test
// the PutWithResponse method.
handler := func(w http.ResponseWriter, req *http.Request) {
io.Copy(w, req.Body)
}
var result params.PublishResponse
err = s.client.PutWithResponse("/~charmers/wily/wordpress-42/publish", publish, &result)
srv := httptest.NewServer(http.HandlerFunc(handler))
defer srv.Close()
client := csclient.New(csclient.Params{
URL: srv.URL,
})

sendBody := "hello"

var result string
err := client.PutWithResponse("/somewhere", sendBody, &result)
c.Assert(err, gc.IsNil)
c.Assert(result.Id, jc.DeepEquals, charm.MustParseURL("~charmers/wily/wordpress-42"))
c.Assert(result, gc.Equals, sendBody)

// Check that the method accepts a nil result.
err = s.client.PutWithResponse("/~charmers/wily/wordpress-42/publish", publish, nil)
err = client.PutWithResponse("/somewhere", sendBody, nil)
c.Assert(err, gc.IsNil)
}

Expand Down Expand Up @@ -992,6 +997,32 @@ func (s *suite) TestDo(c *gc.C) {
c.Assert(string(data), gc.Equals, `"bar"`)
}

func (s *suite) TestWithChannel(c *gc.C) {
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
fmt.Fprint(w, req.URL.Query().Encode())
}))
client := csclient.New(csclient.Params{
URL: srv.URL,
})

makeRequest := func(client *csclient.Client) string {
req, err := http.NewRequest("GET", "", nil)
c.Assert(err, jc.ErrorIsNil)
resp, err := client.DoWithBody(req, "/", nil)
c.Assert(err, jc.ErrorIsNil)
c.Assert(resp.StatusCode, gc.Equals, http.StatusOK)
b, err := ioutil.ReadAll(resp.Body)
c.Assert(err, jc.ErrorIsNil)
return string(b)
}

c.Assert(makeRequest(client), gc.Equals, "")
devClient := client.WithChannel(params.DevelopmentChannel)
c.Assert(makeRequest(devClient), gc.Equals, "channel=development")
// Ensure the original client has not been mutated.
c.Assert(makeRequest(client), gc.Equals, "")
}

var metaBadTypeTests = []struct {
result interface{}
expectError string
Expand Down
41 changes: 41 additions & 0 deletions csclient/params/params.go
Expand Up @@ -35,6 +35,23 @@ const (
Admin = "admin"
)

// Channel is the name of a channel in which an entity may be published.
type Channel string

const (
// DevelopmentChannel is the channel used for charms or bundles under development.
DevelopmentChannel Channel = "development"

// StableChannel is the channel used for stable charms or bundles.
StableChannel Channel = "stable"

// UnpublishedChannel is the default channel to which charms are uploaded.
UnpublishedChannel Channel = "unpublished"

// NoChannel represents where no channel has been specifically requested.
NoChannel Channel = ""
)

// MetaAnyResponse holds the result of a meta/any request.
// See https://github.com/juju/charmstore/blob/v4/docs/API.md#get-idmetaany
type MetaAnyResponse EntityResult
Expand Down Expand Up @@ -242,6 +259,9 @@ type PromulgateRequest struct {
// PublishRequest holds the request of an id/publish PUT request.
// See https://github.com/juju/charmstore/blob/v4/docs/API.md#put-idpublish
type PublishRequest struct {
Channels []Channel
// TODO(rog) remove this when we've updated the charmstore dependency
// to use the new PublishRequest type.
Published bool
// Resources defines the resource revisions to use for the charm.
// Each resource in the charm's metadata.yaml (if any) must have its
Expand All @@ -257,6 +277,27 @@ type PublishResponse struct {
PromulgatedId *charm.URL `json:",omitempty"`
}

// PublishedResponse holds the result of an id/meta/published GET request.
type PublishedResponse struct {
// Channels holds an entry for each channel that the
// entity has been published to.
Info []PublishedInfo
}

// PublishedInfo holds information on a channel that an entity
// has been published to.
type PublishedInfo struct {
// Channel holds the value of the channel that
// the entity has been published to.
// This will never be "unpublished" as entities
// cannot be published to that channel.
Channel Channel

// Current holds whether the entity is the most
// recently published member of the channel.
Current bool
}

// WhoAmIResponse holds the result of a whoami GET request.
// See https://github.com/juju/charmstore/blob/v4/docs/API.md#whoami
type WhoAmIResponse struct {
Expand Down