Skip to content

Commit

Permalink
When showing or finding offers, ignore those with errors and include …
Browse files Browse the repository at this point in the history
…store in output
  • Loading branch information
wallyworld committed Jul 10, 2017
1 parent 13f1c2a commit 12b9e60
Show file tree
Hide file tree
Showing 11 changed files with 110 additions and 65 deletions.
12 changes: 12 additions & 0 deletions apiserver/applicationoffers/applicationoffers_test.go
Expand Up @@ -707,6 +707,11 @@ func (s *applicationOffersSuite) TestFindMulti(c *gc.C) {
ApplicationDescription: "postgresql description",
Endpoints: map[string]charm.Relation{"db": {Name: "postgresql"}},
}
// Include an offer with bad data to ensure it is ignored.
offerAppNotFound := jujucrossmodel.ApplicationOffer{
OfferName: "badoffer",
ApplicationName: "missing",
}

s.applicationOffers.listOffers = func(filters ...jujucrossmodel.ApplicationOfferFilter) ([]jujucrossmodel.ApplicationOffer, error) {
var result []jujucrossmodel.ApplicationOffer
Expand All @@ -718,6 +723,8 @@ func (s *applicationOffersSuite) TestFindMulti(c *gc.C) {
result = append(result, mysqlOffer)
case "hosted-postgresql":
result = append(result, postgresqlOffer)
default:
result = append(result, offerAppNotFound)
}
}
return result, nil
Expand Down Expand Up @@ -801,6 +808,11 @@ func (s *applicationOffersSuite) TestFindMulti(c *gc.C) {
OwnerName: "mary",
ModelName: "another",
},
{
OfferName: "badoffer",
OwnerName: "mary",
ModelName: "another",
},
},
}
found, err := s.api.FindApplicationOffers(filter)
Expand Down
8 changes: 6 additions & 2 deletions apiserver/applicationoffers/base.go
Expand Up @@ -123,8 +123,11 @@ func (api *BaseAPI) applicationOffersFromModel(
isAdmin = userAccess == permission.AdminAccess
}
offerParams, app, err := api.makeOfferParams(backend, &appOffer, userAccess)
// Just because we can't compose the result for one offer, log
// that and move on to the next one.
if err != nil {
return nil, errors.Trace(err)
logger.Warningf("cannot get application offer: %v", err)
continue
}
offer := params.ApplicationOfferDetails{
ApplicationOffer: *offerParams,
Expand All @@ -134,7 +137,8 @@ func (api *BaseAPI) applicationOffersFromModel(
curl, _ := app.CharmURL()
status, err := backend.RemoteConnectionStatus(offer.OfferName)
if err != nil {
return nil, errors.Trace(err)
logger.Warningf("cannot get offer connection status: %v", err)
continue
}
offer.ApplicationName = app.Name()
offer.CharmName = curl.Name
Expand Down
19 changes: 13 additions & 6 deletions cmd/juju/crossmodel/find.go
Expand Up @@ -126,7 +126,7 @@ func (c *findCommand) Run(ctx *cmd.Context) (err error) {
return err
}

output, err := convertFoundOffers(found...)
output, err := convertFoundOffers(c.source, found...)
if err != nil {
return err
}
Expand Down Expand Up @@ -187,17 +187,24 @@ type ApplicationOfferResult struct {

// convertFoundOffers takes any number of api-formatted remote applications and
// creates a collection of ui-formatted applications.
func convertFoundOffers(services ...params.ApplicationOffer) (map[string]ApplicationOfferResult, error) {
if len(services) == 0 {
func convertFoundOffers(store string, offers ...params.ApplicationOffer) (map[string]ApplicationOfferResult, error) {
if len(offers) == 0 {
return nil, nil
}
output := make(map[string]ApplicationOfferResult, len(services))
for _, one := range services {
output := make(map[string]ApplicationOfferResult, len(offers))
for _, one := range offers {
app := ApplicationOfferResult{
Access: one.Access,
Endpoints: convertRemoteEndpoints(one.Endpoints...),
}
output[one.OfferURL] = app
url, err := crossmodel.ParseApplicationURL(one.OfferURL)
if err != nil {
return nil, err
}
if url.Source == "" {
url.Source = store
}
output[url.String()] = app
}
return output, nil
}
31 changes: 16 additions & 15 deletions cmd/juju/crossmodel/find_test.go
Expand Up @@ -45,8 +45,8 @@ func (s *findSuite) TestFindNoArgs(c *gc.C) {
c,
[]string{},
`
URL Access Interfaces
fred/test.hosted-db2 consume http:db2, http:log
Store URL Access Interfaces
master fred/test.hosted-db2 consume http:db2, http:log
`[1:],
)
Expand Down Expand Up @@ -84,8 +84,8 @@ func (s *findSuite) TestSimpleFilter(c *gc.C) {
c,
[]string{"--format", "tabular", "--url", "fred/model.hosted-db2"},
`
URL Access Interfaces
fred/model.hosted-db2 consume http:db2, http:log
Store URL Access Interfaces
master fred/model.hosted-db2 consume http:db2, http:log
`[1:],
)
Expand All @@ -106,8 +106,8 @@ func (s *findSuite) TestEndpointFilter(c *gc.C) {
c,
[]string{"--format", "tabular", "--url", "fred/model", "--endpoint", "db", "--interface", "mysql"},
`
URL Access Interfaces
fred/model.hosted-db2 consume http:db2, http:log
Store URL Access Interfaces
master fred/model.hosted-db2 consume http:db2, http:log
`[1:],
)
Expand All @@ -124,7 +124,7 @@ func (s *findSuite) TestFindYaml(c *gc.C) {
c,
[]string{"fred/model.hosted-db2", "--format", "yaml"},
`
fred/model.hosted-db2:
master:fred/model.hosted-db2:
access: consume
endpoints:
db2:
Expand All @@ -143,8 +143,8 @@ func (s *findSuite) TestFindTabular(c *gc.C) {
c,
[]string{"fred/model.hosted-db2", "--format", "tabular"},
`
URL Access Interfaces
fred/model.hosted-db2 consume http:db2, http:log
Store URL Access Interfaces
master fred/model.hosted-db2 consume http:db2, http:log
`[1:],
)
Expand All @@ -155,10 +155,10 @@ func (s *findSuite) TestFindDifferentController(c *gc.C) {
s.mockAPI.controllerName = "different"
s.assertFind(
c,
[]string{"different:fred/model.hosted-db2", "--format", "tabular"},
[]string{"fred/model.hosted-db2", "--format", "tabular"},
`
URL Access Interfaces
different:fred/model.hosted-db2 consume http:db2, http:log
Store URL Access Interfaces
different fred/model.hosted-db2 consume http:db2, http:log
`[1:],
)
Expand Down Expand Up @@ -202,10 +202,11 @@ func (s mockFindAPI) FindApplicationOffers(filters ...jujucrossmodel.Application
if s.results != nil {
return s.results, nil
}
offerURL := fmt.Sprintf("fred/%s.%s", s.expectedModelName, s.offerName)
if s.controllerName != "" {
offerURL = s.controllerName + ":" + offerURL
store := s.controllerName
if store == "" {
store = "master"
}
offerURL := fmt.Sprintf("%s:fred/%s.%s", store, s.expectedModelName, s.offerName)
return []params.ApplicationOffer{{
OfferURL: offerURL,
OfferName: s.offerName,
Expand Down
14 changes: 10 additions & 4 deletions cmd/juju/crossmodel/findformatter.go
Expand Up @@ -12,6 +12,7 @@ import (
"github.com/juju/errors"

"github.com/juju/juju/cmd/output"
"github.com/juju/juju/core/crossmodel"
)

// formatFindTabular returns a tabular summary of remote applications or
Expand All @@ -28,17 +29,22 @@ func formatFindTabular(writer io.Writer, value interface{}) error {
func formatFoundEndpointsTabular(writer io.Writer, all map[string]ApplicationOfferResult) error {
tw := output.TabWriter(writer)
w := output.Wrapper{tw}
w.Println("URL", "Access", "Interfaces")
w.Println("Store", "URL", "Access", "Interfaces")

for url, one := range all {
applicationURL := url
for urlStr, one := range all {
url, err := crossmodel.ParseApplicationURL(urlStr)
if err != nil {
return err
}
store := url.Source
url.Source = ""

interfaces := []string{}
for name, ep := range one.Endpoints {
interfaces = append(interfaces, fmt.Sprintf("%s:%s", ep.Interface, name))
}
sort.Strings(interfaces)
w.Println(applicationURL, one.Access, strings.Join(interfaces, ", "))
w.Println(store, url.String(), one.Access, strings.Join(interfaces, ", "))
}
tw.Flush()

Expand Down
13 changes: 10 additions & 3 deletions cmd/juju/crossmodel/show.go
Expand Up @@ -103,7 +103,7 @@ func (c *showCommand) Run(ctx *cmd.Context) (err error) {
return err
}

output, err := convertOffers(found)
output, err := convertOffers(controllerName, found)
if err != nil {
return err
}
Expand Down Expand Up @@ -131,7 +131,7 @@ type ShowOfferedApplication struct {

// convertOffers takes any number of api-formatted remote applications and
// creates a collection of ui-formatted offers.
func convertOffers(offers ...params.ApplicationOffer) (map[string]ShowOfferedApplication, error) {
func convertOffers(store string, offers ...params.ApplicationOffer) (map[string]ShowOfferedApplication, error) {
if len(offers) == 0 {
return nil, nil
}
Expand All @@ -144,7 +144,14 @@ func convertOffers(offers ...params.ApplicationOffer) (map[string]ShowOfferedApp
if one.ApplicationDescription != "" {
app.Description = one.ApplicationDescription
}
output[one.OfferURL] = app
url, err := crossmodel.ParseApplicationURL(one.OfferURL)
if err != nil {
return nil, err
}
if url.Source == "" {
url.Source = store
}
output[url.String()] = app
}
return output, nil
}
38 changes: 19 additions & 19 deletions cmd/juju/crossmodel/show_test.go
Expand Up @@ -52,7 +52,7 @@ func (s *showSuite) TestShowYaml(c *gc.C) {
c,
[]string{"fred/model.db2", "--format", "yaml"},
`
fred/model.db2:
test-master:fred/model.db2:
access: consume
endpoints:
db2:
Expand All @@ -71,9 +71,9 @@ func (s *showSuite) TestShowTabular(c *gc.C) {
c,
[]string{"fred/model.db2", "--format", "tabular"},
`
URL Access Description Endpoint Interface Role
fred/model.db2 consume IBM DB2 Express Server Edition is an entry db2 http requirer
level database system log http provider
Store URL Access Description Endpoint Interface Role
test-master fred/model.db2 consume IBM DB2 Express Server Edition is an entry db2 http requirer
level database system log http provider
`[1:],
)
Expand All @@ -85,9 +85,9 @@ func (s *showSuite) TestShowDifferentController(c *gc.C) {
c,
[]string{"different:fred/model.db2", "--format", "tabular"},
`
URL Access Description Endpoint Interface Role
different:fred/model.db2 consume IBM DB2 Express Server Edition is an entry db2 http requirer
level database system log http provider
Store URL Access Description Endpoint Interface Role
different fred/model.db2 consume IBM DB2 Express Server Edition is an entry db2 http requirer
level database system log http provider
`[1:],
)
Expand All @@ -99,12 +99,12 @@ func (s *showSuite) TestShowTabularExactly180Desc(c *gc.C) {
c,
[]string{"fred/model.db2", "--format", "tabular"},
`
URL Access Description Endpoint Interface Role
fred/model.db2 consume IBM DB2 Express Server Edition is an entry db2 http requirer
level database systemIBM DB2 Express Server log http provider
Edition is an entry level database systemIBM
DB2 Express Server Edition is an entry level
dat
Store URL Access Description Endpoint Interface Role
test-master fred/model.db2 consume IBM DB2 Express Server Edition is an entry db2 http requirer
level database systemIBM DB2 Express Server log http provider
Edition is an entry level database systemIBM
DB2 Express Server Edition is an entry level
dat
`[1:],
)
Expand All @@ -116,12 +116,12 @@ func (s *showSuite) TestShowTabularMoreThan180Desc(c *gc.C) {
c,
[]string{"fred/model.db2", "--format", "tabular"},
`
URL Access Description Endpoint Interface Role
fred/model.db2 consume IBM DB2 Express Server Edition is an entry db2 http requirer
level database systemIBM DB2 Express Server log http provider
Edition is an entry level database systemIBM
DB2 Express Server Edition is an entry level
...
Store URL Access Description Endpoint Interface Role
test-master fred/model.db2 consume IBM DB2 Express Server Edition is an entry db2 http requirer
level database systemIBM DB2 Express Server log http provider
Edition is an entry level database systemIBM
DB2 Express Server Edition is an entry level
...
`[1:],
)
Expand Down
18 changes: 13 additions & 5 deletions cmd/juju/crossmodel/showformatter.go
Expand Up @@ -12,6 +12,7 @@ import (
"github.com/juju/errors"

"github.com/juju/juju/cmd/output"
"github.com/juju/juju/core/crossmodel"
)

const (
Expand All @@ -37,10 +38,16 @@ func formatOfferedEndpointsTabular(writer io.Writer, all map[string]ShowOfferedA
tw := output.TabWriter(writer)
w := output.Wrapper{tw}

w.Println("URL", "Access", "Description", "Endpoint", "Interface", "Role")
w.Println("Store", "URL", "Access", "Description", "Endpoint", "Interface", "Role")

for name, one := range all {
offerName := name
for urlStr, one := range all {
url, err := crossmodel.ParseApplicationURL(urlStr)
if err != nil {
return err
}
store := url.Source
url.Source = ""
offerURL := url.String()
offerAccess := one.Access
offerDesc := one.Description

Expand All @@ -63,9 +70,10 @@ func formatOfferedEndpointsTabular(writer io.Writer, all map[string]ShowOfferedA
for i := 0; i < maxIterations; i++ {
descLine := descAt(descLines, i)
name, endpoint := endpointAt(one.Endpoints, names, i)
w.Println(offerName, offerAccess, descLine, name, endpoint.Interface, endpoint.Role)
w.Println(store, offerURL, offerAccess, descLine, name, endpoint.Interface, endpoint.Role)
// Only print once.
offerName = ""
store = ""
offerURL = ""
offerAccess = ""
}
}
Expand Down
2 changes: 1 addition & 1 deletion cmd/juju/status/output_tabular.go
Expand Up @@ -125,7 +125,7 @@ func FormatTabular(writer io.Writer, forceColor bool, value interface{}) error {
p(values...)

if len(fs.RemoteApplications) > 0 {
outputHeaders("SAAS name", "Status", "Store", "URL")
outputHeaders("SAAS", "Status", "Store", "URL")
for _, appName := range utils.SortStringsNaturally(stringKeysFromMap(fs.RemoteApplications)) {
app := fs.RemoteApplications[appName]
var store, urlPath string
Expand Down
2 changes: 1 addition & 1 deletion cmd/juju/status/status_test.go
Expand Up @@ -4037,7 +4037,7 @@ func (s *StatusSuite) testStatusWithFormatTabular(c *gc.C, useFeatureFlag bool)
Model Controller Cloud/Region Version Notes SLA
controller kontroll dummy/dummy-region 1.2.3 upgrade available: 1.2.4 unsupported
SAAS name Status Store URL
SAAS Status Store URL
hosted-riak unknown local me/model.riak
App Version Status Scale Charm Store Rev OS Notes
Expand Down

0 comments on commit 12b9e60

Please sign in to comment.