Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings
/jujuPublic

Commit0ab3a2d

Browse files
authored
Merge pull request#21136 from hmlanigan/fix-find-offers
#21136To ensure that an offer is found with `juju find-offers` add filters for each model on the controller if none is specified. The logic for GetOffers is model domain specific, thus we need to include the different models if not already provided.Reenable CI test line disabled in 21115, how that `juju find-offers` is working.## Checklist- [x] Code style: imports ordered, good names, simple structure, etc- [x] Comments saying why design decisions were made- [x] Go unit tests, with comments saying what you're testing- [ ] ~[Integration tests](https://github.com/juju/juju/tree/main/tests), with comments saying what you're testing~- [ ] ~[doc.go](https://discourse.charmhub.io/t/readme-in-packages/451) added or updated in changed packages~## QA steps```$ juju add-model offer ; juju deploy juju-qa-dummy-sink sink ; juju offer sink:source; juju add-model consume ; juju deploy juju-qa-dummy-source source$ juju find-offersStore URL Access Interfacesfix-find-offers admin/offer.sink admin dummy-token:source```
2 parentsfc24d2b +8b6f05c commit0ab3a2d

File tree

5 files changed

+198
-85
lines changed

5 files changed

+198
-85
lines changed

‎apiserver/facades/client/applicationoffers/applicationoffers.go‎

Lines changed: 47 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -467,30 +467,36 @@ func makeOfferFilterFromParams(filter params.OfferFilter) (crossmodelrelationser
467467
OfferName:offerName,
468468
ApplicationName:filter.ApplicationName,
469469
ApplicationDescription:filter.ApplicationDescription,
470-
Endpoints:make([]crossmodelrelationservice.EndpointFilterTerm,len(filter.Endpoints)),
471-
AllowedConsumers:make([]string,len(filter.AllowedConsumerTags)),
472-
ConnectedUsers:make([]string,len(filter.ConnectedUserTags)),
473470
}
474-
fori,ep:=rangefilter.Endpoints {
475-
offerFilter.Endpoints[i]= crossmodelrelationservice.EndpointFilterTerm{
476-
Name:ep.Name,
477-
Interface:ep.Interface,
478-
Role:domaincharm.RelationRole(ep.Role),
471+
iflen(filter.Endpoints)>0 {
472+
offerFilter.Endpoints=make([]crossmodelrelationservice.EndpointFilterTerm,len(filter.Endpoints))
473+
fori,ep:=rangefilter.Endpoints {
474+
offerFilter.Endpoints[i]= crossmodelrelationservice.EndpointFilterTerm{
475+
Name:ep.Name,
476+
Interface:ep.Interface,
477+
Role:domaincharm.RelationRole(ep.Role),
478+
}
479479
}
480480
}
481-
fori,tag:=rangefilter.AllowedConsumerTags {
482-
u,err:=names.ParseUserTag(tag)
483-
iferr!=nil {
484-
return crossmodelrelationservice.OfferFilter{},errors.Capture(err)
481+
iflen(filter.AllowedConsumerTags)>0 {
482+
offerFilter.AllowedConsumers=make([]string,len(filter.AllowedConsumerTags))
483+
fori,tag:=rangefilter.AllowedConsumerTags {
484+
u,err:=names.ParseUserTag(tag)
485+
iferr!=nil {
486+
return crossmodelrelationservice.OfferFilter{},errors.Capture(err)
487+
}
488+
offerFilter.AllowedConsumers[i]=u.Id()
485489
}
486-
offerFilter.AllowedConsumers[i]=u.Id()
487490
}
488-
fori,tag:=rangefilter.ConnectedUserTags {
489-
u,err:=names.ParseUserTag(tag)
490-
iferr!=nil {
491-
return crossmodelrelationservice.OfferFilter{},errors.Capture(err)
491+
iflen(filter.ConnectedUserTags)>0 {
492+
offerFilter.ConnectedUsers=make([]string,len(filter.ConnectedUserTags))
493+
fori,tag:=rangefilter.ConnectedUserTags {
494+
u,err:=names.ParseUserTag(tag)
495+
iferr!=nil {
496+
return crossmodelrelationservice.OfferFilter{},errors.Capture(err)
497+
}
498+
offerFilter.ConnectedUsers[i]=u.Id()
492499
}
493-
offerFilter.ConnectedUsers[i]=u.Id()
494500
}
495501
returnofferFilter,nil
496502
}
@@ -809,14 +815,34 @@ func filterFromURL(url corecrossmodel.OfferURL) params.OfferFilter {
809815

810816
// FindApplicationOffers gets details about remote applications that match given filter.
811817
func (api*OffersAPI)FindApplicationOffers(ctx context.Context,filters params.OfferFilters) (params.QueryApplicationOffersResultsV5,error) {
812-
varresult params.QueryApplicationOffersResultsV5
813-
818+
var (
819+
result params.QueryApplicationOffersResultsV5
820+
filtersToUse params.OfferFilters
821+
)
822+
823+
// If there is only one filter term, and no model is specified, add in
824+
// any models the user can see and query across those.
825+
// If there's more than one filter term, each must specify a model.
826+
iflen(filters.Filters)==1&&filters.Filters[0].ModelName=="" {
827+
models,err:=api.modelService.ListAllModels(ctx)
828+
iferr!=nil {
829+
returnresult,errors.Capture(err)
830+
}
831+
for_,m:=rangemodels {
832+
modelFilter:=filters.Filters[0]
833+
modelFilter.ModelName=m.Name
834+
modelFilter.ModelQualifier=m.Qualifier.String()
835+
filtersToUse.Filters=append(filtersToUse.Filters,modelFilter)
836+
}
837+
}else {
838+
filtersToUse=filters
839+
}
814840
apiUser,ok:=api.authorizer.GetAuthTag().(names.UserTag)
815841
if!ok {
816842
return params.QueryApplicationOffersResultsV5{},apiservererrors.ErrPerm
817843
}
818844

819-
offers,err:=api.getApplicationOffersDetails(ctx,apiUser,permission.ReadAccess,filters)
845+
offers,err:=api.getApplicationOffersDetails(ctx,apiUser,permission.ReadAccess,filtersToUse)
820846
iferr!=nil {
821847
returnresult,apiservererrors.ServerError(err)
822848
}

‎apiserver/facades/client/applicationoffers/applicationoffers_test.go‎

Lines changed: 106 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -623,15 +623,9 @@ func (s *offerSuite) TestListApplicationOffers(c *tc.C) {
623623

624624
domainFilters:= []crossmodelrelationservice.OfferFilter{
625625
{
626-
OfferName:"hosted-db2",
627-
Endpoints:make([]crossmodelrelationservice.EndpointFilterTerm,0),
628-
AllowedConsumers:make([]string,0),
629-
ConnectedUsers:make([]string,0),
626+
OfferName:"hosted-db2",
630627
}, {
631-
OfferName:"testing",
632-
Endpoints:make([]crossmodelrelationservice.EndpointFilterTerm,0),
633-
AllowedConsumers:make([]string,0),
634-
ConnectedUsers:make([]string,0),
628+
OfferName:"testing",
635629
},
636630
}
637631
charmLocator:= charm.CharmLocator{
@@ -737,15 +731,9 @@ func (s *offerSuite) TestListApplicationOffersError(c *tc.C) {
737731

738732
domainFilters:= []crossmodelrelationservice.OfferFilter{
739733
{
740-
OfferName:"hosted-db2",
741-
Endpoints:make([]crossmodelrelationservice.EndpointFilterTerm,0),
742-
AllowedConsumers:make([]string,0),
743-
ConnectedUsers:make([]string,0),
734+
OfferName:"hosted-db2",
744735
}, {
745-
OfferName:"testing",
746-
Endpoints:make([]crossmodelrelationservice.EndpointFilterTerm,0),
747-
AllowedConsumers:make([]string,0),
748-
ConnectedUsers:make([]string,0),
736+
OfferName:"testing",
749737
},
750738
}
751739
s.crossModelRelationService.EXPECT().GetOffers(gomock.Any(),domainFilters).Return(nil,errors.New("some error"))
@@ -834,15 +822,9 @@ func (s *offerSuite) TestFindApplicationOffers(c *tc.C) {
834822

835823
domainFilters:= []crossmodelrelationservice.OfferFilter{
836824
{
837-
OfferName:"hosted-db2",
838-
Endpoints:make([]crossmodelrelationservice.EndpointFilterTerm,0),
839-
AllowedConsumers:make([]string,0),
840-
ConnectedUsers:make([]string,0),
825+
OfferName:"hosted-db2",
841826
}, {
842-
OfferName:"testing",
843-
Endpoints:make([]crossmodelrelationservice.EndpointFilterTerm,0),
844-
AllowedConsumers:make([]string,0),
845-
ConnectedUsers:make([]string,0),
827+
OfferName:"testing",
846828
},
847829
}
848830
charmLocator:= charm.CharmLocator{
@@ -925,6 +907,97 @@ func (s *offerSuite) TestFindApplicationOffers(c *tc.C) {
925907
})
926908
}
927909

910+
func (s*offerSuite)TestFindApplicationOffersAllOffers(c*tc.C) {
911+
defers.setupMocks(c).Finish()
912+
913+
// Arrange
914+
offerAPI:=s.offerAPI(c)
915+
adminTag:=s.setupAuthUser(user.AdminUserName.Name())
916+
adminUser:= user.User{DisplayName:"fred smith"}
917+
s.accessService.EXPECT().GetUserByName(gomock.Any(),user.NameFromTag(adminTag)).Return(adminUser,nil)
918+
s.expectEntityHasPermissionMissingPermission(adminTag,permission.SuperuserAccess)
919+
920+
s.expectEntityHasPermission(adminTag,permission.ReadAccess)
921+
922+
modelName:="prod"
923+
modelOwnerTag:=names.NewUserTag("fred@external")
924+
925+
foundModel:= model.Model{
926+
Name:modelName,
927+
Qualifier:model.QualifierFromUserTag(modelOwnerTag),
928+
UUID:modeltesting.GenModelUUID(c),
929+
}
930+
s.modelService.EXPECT().ListAllModels(gomock.Any()).Return([]model.Model{foundModel},nil)
931+
s.modelService.EXPECT().GetModelByNameAndQualifier(gomock.Any(),modelName,foundModel.Qualifier).Return(foundModel,nil)
932+
933+
charmLocator:= charm.CharmLocator{
934+
Name:"app",
935+
Revision:42,
936+
Source:charm.CharmHubSource,
937+
Architecture:architecture.AMD64,
938+
}
939+
offerDetails:= []*crossmodelrelation.OfferDetail{
940+
{
941+
OfferUUID:uuid.MustNewUUID().String(),
942+
OfferName:"hosted-db2",
943+
ApplicationName:"test-app",
944+
ApplicationDescription:"testing application",
945+
CharmLocator:charmLocator,
946+
Endpoints: []crossmodelrelation.OfferEndpoint{
947+
{Name:"db"},
948+
},
949+
OfferUsers: []crossmodelrelation.OfferUser{{Name:"george",Access:permission.ConsumeAccess}},
950+
}, {
951+
OfferUUID:uuid.MustNewUUID().String(),
952+
OfferName:"testing",
953+
ApplicationName:"test-app",
954+
ApplicationDescription:"testing application",
955+
CharmLocator:charmLocator,
956+
Endpoints: []crossmodelrelation.OfferEndpoint{
957+
{Name:"endpoint"},
958+
},
959+
OfferUsers: []crossmodelrelation.OfferUser{{Name:"admin",Access:permission.AdminAccess}},
960+
},
961+
}
962+
s.crossModelRelationService.EXPECT().GetOffers(gomock.Any(), []crossmodelrelationservice.OfferFilter{{}}).Return(offerDetails,nil)
963+
964+
filters:= params.OfferFilters{Filters: []params.OfferFilter{{}}}
965+
966+
// Act
967+
obtained,err:=offerAPI.FindApplicationOffers(c.Context(),filters)
968+
969+
// Assert
970+
c.Assert(err,tc.IsNil)
971+
c.Assert(obtained.Results,tc.HasLen,2)
972+
mc:=tc.NewMultiChecker()
973+
mc.AddExpr("_.ApplicationOfferDetailsV5.SourceModelTag",tc.Ignore)
974+
mc.AddExpr("_.ApplicationOfferDetailsV5.OfferUUID",tc.IsUUID)
975+
c.Check(obtained.Results[0],mc, params.ApplicationOfferAdminDetailsV5{
976+
ApplicationOfferDetailsV5: params.ApplicationOfferDetailsV5{
977+
OfferURL:"fred-external/prod.hosted-db2",
978+
OfferName:"hosted-db2",
979+
ApplicationDescription:"testing application",
980+
Endpoints: []params.RemoteEndpoint{{Name:"db"}},
981+
Users: []params.OfferUserDetails{
982+
{UserName:"admin",DisplayName:"fred smith",Access:"admin"},
983+
}},
984+
ApplicationName:"test-app",
985+
CharmURL:"ch:amd64/app-42",
986+
})
987+
c.Check(obtained.Results[1],mc, params.ApplicationOfferAdminDetailsV5{
988+
ApplicationOfferDetailsV5: params.ApplicationOfferDetailsV5{
989+
OfferURL:"fred-external/prod.testing",
990+
OfferName:"testing",
991+
ApplicationDescription:"testing application",
992+
Endpoints: []params.RemoteEndpoint{{Name:"endpoint"}},
993+
Users: []params.OfferUserDetails{
994+
{UserName:"admin",DisplayName:"fred smith",Access:"admin"},
995+
}},
996+
ApplicationName:"test-app",
997+
CharmURL:"ch:amd64/app-42",
998+
})
999+
}
1000+
9281001
func (s*offerSuite)TestFindApplicationOffersPermission(c*tc.C) {
9291002
defers.setupMocks(c).Finish()
9301003

@@ -986,15 +1059,9 @@ func (s *offerSuite) TestFindApplicationOffersError(c *tc.C) {
9861059

9871060
domainFilters:= []crossmodelrelationservice.OfferFilter{
9881061
{
989-
OfferName:"hosted-db2",
990-
Endpoints:make([]crossmodelrelationservice.EndpointFilterTerm,0),
991-
AllowedConsumers:make([]string,0),
992-
ConnectedUsers:make([]string,0),
1062+
OfferName:"hosted-db2",
9931063
}, {
994-
OfferName:"testing",
995-
Endpoints:make([]crossmodelrelationservice.EndpointFilterTerm,0),
996-
AllowedConsumers:make([]string,0),
997-
ConnectedUsers:make([]string,0),
1064+
OfferName:"testing",
9981065
},
9991066
}
10001067
s.crossModelRelationService.EXPECT().GetOffers(gomock.Any(),domainFilters).Return(nil,errors.New("some error"))
@@ -1109,15 +1176,9 @@ func (s *offerSuite) TestApplicationOffers(c *tc.C) {
11091176

11101177
domainFilters:= []crossmodelrelationservice.OfferFilter{
11111178
{
1112-
OfferName:"hosted-db2",
1113-
Endpoints:make([]crossmodelrelationservice.EndpointFilterTerm,0),
1114-
AllowedConsumers:make([]string,0),
1115-
ConnectedUsers:make([]string,0),
1179+
OfferName:"hosted-db2",
11161180
}, {
1117-
OfferName:"testing",
1118-
Endpoints:make([]crossmodelrelationservice.EndpointFilterTerm,0),
1119-
AllowedConsumers:make([]string,0),
1120-
ConnectedUsers:make([]string,0),
1181+
OfferName:"testing",
11211182
},
11221183
}
11231184
charmLocator:= charm.CharmLocator{
@@ -1216,10 +1277,7 @@ func (s *offerSuite) TestApplicationOffersMixSuccessAndFail(c *tc.C) {
12161277

12171278
domainFilters:= []crossmodelrelationservice.OfferFilter{
12181279
{
1219-
OfferName:"testing",
1220-
Endpoints:make([]crossmodelrelationservice.EndpointFilterTerm,0),
1221-
AllowedConsumers:make([]string,0),
1222-
ConnectedUsers:make([]string,0),
1280+
OfferName:"testing",
12231281
},
12241282
}
12251283
charmLocator:= charm.CharmLocator{
@@ -1294,10 +1352,7 @@ func (s *offerSuite) TestApplicationOffersNotFound(c *tc.C) {
12941352

12951353
domainFilters:= []crossmodelrelationservice.OfferFilter{
12961354
{
1297-
OfferName:"testing",
1298-
Endpoints:make([]crossmodelrelationservice.EndpointFilterTerm,0),
1299-
AllowedConsumers:make([]string,0),
1300-
ConnectedUsers:make([]string,0),
1355+
OfferName:"testing",
13011356
},
13021357
}
13031358
offerDetails:= []*crossmodelrelation.OfferDetail{}
@@ -1454,10 +1509,7 @@ func (s *offerSuite) testGetConsumeDetails(c *tc.C, userID string) {
14541509

14551510
domainFilters:= []crossmodelrelationservice.OfferFilter{
14561511
{
1457-
OfferName:"hosted-mysql",
1458-
Endpoints:make([]crossmodelrelationservice.EndpointFilterTerm,0),
1459-
AllowedConsumers:make([]string,0),
1460-
ConnectedUsers:make([]string,0),
1512+
OfferName:"hosted-mysql",
14611513
},
14621514
}
14631515
charmLocator:= charm.CharmLocator{
@@ -1551,10 +1603,7 @@ func (s *offerSuite) TestGetConsumeDetailsUser(c *tc.C) {
15511603

15521604
domainFilters:= []crossmodelrelationservice.OfferFilter{
15531605
{
1554-
OfferName:"hosted-mysql",
1555-
Endpoints:make([]crossmodelrelationservice.EndpointFilterTerm,0),
1556-
AllowedConsumers:make([]string,0),
1557-
ConnectedUsers:make([]string,0),
1606+
OfferName:"hosted-mysql",
15581607
},
15591608
}
15601609
charmLocator:= charm.CharmLocator{
@@ -1677,10 +1726,7 @@ func (s *offerSuite) TestGetConsumeDetailsNoOffers(c *tc.C) {
16771726

16781727
domainFilters:= []crossmodelrelationservice.OfferFilter{
16791728
{
1680-
OfferName:"hosted-mysql",
1681-
Endpoints:make([]crossmodelrelationservice.EndpointFilterTerm,0),
1682-
AllowedConsumers:make([]string,0),
1683-
ConnectedUsers:make([]string,0),
1729+
OfferName:"hosted-mysql",
16841730
},
16851731
}
16861732

‎apiserver/facades/client/applicationoffers/package_mock_test.go‎

Lines changed: 39 additions & 0 deletions
Some generated files are not rendered by default. Learn more aboutcustomizing how changed files appear on GitHub.

‎apiserver/facades/client/applicationoffers/service.go‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,10 @@ type AccessService interface {
3838

3939
// ModelService defines the interface for interacting with the model domain.
4040
typeModelServiceinterface {
41+
// ListAllModels returns a slice of all models in the controller. If no models
42+
// exist an empty slice is returned.
43+
ListAllModels(ctx context.Context) ([]coremodel.Model,error)
44+
4145
// GetModelByNameAndQualifier returns the model associated with the given
4246
// model name and qualifier.
4347
GetModelByNameAndQualifier(

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp