Skip to content

Commit

Permalink
Add implementation for the core API service. (#6948)
Browse files Browse the repository at this point in the history
### Description of the change

Follows on from #6941 , adding the implementation for the core API
service.

Next PR will add the implementation for the helm plugin using the OCI
distribution spec API so that we can investigate UX options for
displaying the data.

### Benefits

<!-- What benefits will be realized by the code change? -->

### Possible drawbacks

<!-- Describe any known limitations with your change -->

### Applicable issues

<!-- Enter any applicable Issues here (You can reference an issue using
#) -->

- ref #6548 

### Additional information

<!-- If there's anything else that's important and relevant to your pull
request, mention that information here.-->

Signed-off-by: Michael Nelson <minelson@vmware.com>
  • Loading branch information
absoludity authored Nov 14, 2023
1 parent adc4a9a commit 559f82f
Show file tree
Hide file tree
Showing 4 changed files with 121 additions and 5 deletions.
24 changes: 23 additions & 1 deletion cmd/kubeapps-apis/core/packages/v1alpha1/packages.go
Original file line number Diff line number Diff line change
Expand Up @@ -356,7 +356,29 @@ func (s packagesServer) DeleteInstalledPackage(ctx context.Context, request *con
}

func (s packagesServer) GetAvailablePackageMetadatas(ctx context.Context, request *connect.Request[packages.GetAvailablePackageMetadatasRequest]) (*connect.Response[packages.GetAvailablePackageMetadatasResponse], error) {
return nil, connect.NewError(connect.CodeUnimplemented, fmt.Errorf("Unimplemented"))
log.InfoS("+core GetAvailablePackageVersions", "cluster", request.Msg.GetAvailablePackageRef().GetContext().GetCluster(), "namespace", request.Msg.GetAvailablePackageRef().GetContext().GetNamespace())

if request.Msg.GetAvailablePackageRef().GetPlugin() == nil {
return nil, connect.NewError(connect.CodeInvalidArgument, fmt.Errorf("Unable to retrieve the plugin (missing AvailablePackageRef.Plugin)"))
}

// Retrieve the plugin with server matching the requested plugin name
pluginWithServer := s.getPluginWithServer(request.Msg.AvailablePackageRef.Plugin)
if pluginWithServer == nil {
return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("Unable to get the plugin %v", request.Msg.AvailablePackageRef.Plugin))
}

// Get the response from the requested plugin
ctxForPlugin := updateContextWithAuthz(ctx, request.Header())
response, err := pluginWithServer.server.GetAvailablePackageMetadatas(ctxForPlugin, request)
if err != nil {
return nil, connect.NewError(connect.CodeOf(err), fmt.Errorf("Unable to get the available package metadatas for the package %q using the plugin %q: %w", request.Msg.AvailablePackageRef.Identifier, request.Msg.AvailablePackageRef.Plugin.Name, err))
}

// Build the response
return connect.NewResponse(&packages.GetAvailablePackageMetadatasResponse{
PackageMetadata: response.Msg.PackageMetadata,
}), nil
}

// getPluginWithServer returns the *pkgPluginsWithServer from a given packagesServer
Expand Down
78 changes: 78 additions & 0 deletions cmd/kubeapps-apis/core/packages/v1alpha1/packages_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ var ignoreUnexportedOpts = cmpopts.IgnoreUnexported(
corev1.AvailablePackageSummary{},
corev1.Context{},
corev1.GetAvailablePackageDetailResponse{},
corev1.GetAvailablePackageMetadatasResponse{},
corev1.GetAvailablePackageSummariesResponse{},
corev1.GetAvailablePackageVersionsResponse{},
corev1.GetInstalledPackageResourceRefsResponse{},
Expand All @@ -43,6 +44,7 @@ var ignoreUnexportedOpts = cmpopts.IgnoreUnexported(
corev1.InstalledPackageSummary{},
corev1.Maintainer{},
corev1.PackageAppVersion{},
corev1.PackageMetadata{},
corev1.VersionReference{},
corev1.ResourceRef{},
plugins.Plugin{},
Expand All @@ -57,6 +59,9 @@ func makeDefaultTestPackagingPlugin(pluginName string) pkgPluginWithServer {
plugin_test.MakeAvailablePackageSummary("pkg-2", pluginDetails),
}
packagingPluginServer.AvailablePackageDetail = plugin_test.MakeAvailablePackageDetail("pkg-1", pluginDetails)
packagingPluginServer.AvailablePackageMetadatas = []*corev1.PackageMetadata{
plugin_test.MakeAvailablePackageMetadata("media-type-1", "name-1", "description-1", "oci://location-1"),
}
packagingPluginServer.InstalledPackageSummaries = []*corev1.InstalledPackageSummary{
plugin_test.MakeInstalledPackageSummary("pkg-1", pluginDetails),
plugin_test.MakeInstalledPackageSummary("pkg-2", pluginDetails),
Expand Down Expand Up @@ -373,6 +378,79 @@ func TestGetAvailablePackageDetail(t *testing.T) {
}
}

func TestGetAvailablePackageMetadatas(t *testing.T) {
testCases := []struct {
name string
configuredPlugins []pkgPluginWithServer
errorCode connect.Code
request *corev1.GetAvailablePackageMetadatasRequest
expectedResponse *corev1.GetAvailablePackageMetadatasResponse
}{
{
name: "it should successfully call the core GetAvailablePackageMetadatas operation",
configuredPlugins: []pkgPluginWithServer{
mockedPackagingPlugin1,
},
request: &corev1.GetAvailablePackageMetadatasRequest{
AvailablePackageRef: &corev1.AvailablePackageReference{
Context: &corev1.Context{
Cluster: "",
Namespace: globalPackagingNamespace,
},
Identifier: "pkg-1",
Plugin: mockedPackagingPlugin1.plugin,
},
PkgVersion: "1.0",
},

expectedResponse: &corev1.GetAvailablePackageMetadatasResponse{
PackageMetadata: []*corev1.PackageMetadata{
plugin_test.MakeAvailablePackageMetadata("media-type-1", "name-1", "description-1", "oci://location-1"),
},
},
},
{
name: "it should fail when calling the core GetAvailablePackageMetadatas operation when the package is not present in a plugin",
configuredPlugins: []pkgPluginWithServer{
mockedNotFoundPackagingPlugin,
},
request: &corev1.GetAvailablePackageMetadatasRequest{
AvailablePackageRef: &corev1.AvailablePackageReference{
Context: &corev1.Context{
Cluster: "",
Namespace: globalPackagingNamespace,
},
Identifier: "pkg-1",
Plugin: mockedNotFoundPackagingPlugin.plugin,
},
PkgVersion: "",
},

expectedResponse: &corev1.GetAvailablePackageMetadatasResponse{},
errorCode: connect.CodeNotFound,
},
}

for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
server := &packagesServer{
pluginsWithServers: tc.configuredPlugins,
}
availablePackageDetail, err := server.GetAvailablePackageMetadatas(context.Background(), connect.NewRequest(tc.request))

if got, want := connect.CodeOf(err), tc.errorCode; err != nil && got != want {
t.Fatalf("got: %+v, want: %+v, err: %+v", got, want, err)
}

if tc.errorCode == 0 {
if got, want := availablePackageDetail.Msg, tc.expectedResponse; !cmp.Equal(got, want, ignoreUnexportedOpts) {
t.Errorf("mismatch (-want +got):\n%s", cmp.Diff(want, got, ignoreUnexportedOpts))
}
}
})
}
}

func TestGetInstalledPackageSummaries(t *testing.T) {
testCases := []struct {
name string
Expand Down
15 changes: 11 additions & 4 deletions cmd/kubeapps-apis/plugin_test/mock_plugin.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ type TestPackagingPluginServer struct {
Plugin *plugins.Plugin
AvailablePackageSummaries []*corev1.AvailablePackageSummary
AvailablePackageDetail *corev1.AvailablePackageDetail
AvailablePackageMetadatas []*corev1.PackageMetadata
InstalledPackageSummaries []*corev1.InstalledPackageSummary
InstalledPackageDetail *corev1.InstalledPackageDetail
PackageAppVersions []*corev1.PackageAppVersion
Expand Down Expand Up @@ -66,6 +67,16 @@ func (s TestPackagingPluginServer) GetAvailablePackageDetail(ctx context.Context
}), nil
}

// GetAvailablePackageMetadatas returns the package metadatas based on the request.
func (s TestPackagingPluginServer) GetAvailablePackageMetadatas(ctx context.Context, request *connect.Request[corev1.GetAvailablePackageMetadatasRequest]) (*connect.Response[corev1.GetAvailablePackageMetadatasResponse], error) {
if s.ErrorCode != 0 {
return nil, connect.NewError(s.ErrorCode, fmt.Errorf("Non-OK response"))
}
return connect.NewResponse(&corev1.GetAvailablePackageMetadatasResponse{
PackageMetadata: s.AvailablePackageMetadatas,
}), nil
}

// GetInstalledPackageSummaries returns the installed package summaries based on the request.
func (s TestPackagingPluginServer) GetInstalledPackageSummaries(ctx context.Context, request *connect.Request[corev1.GetInstalledPackageSummariesRequest]) (*connect.Response[corev1.GetInstalledPackageSummariesResponse], error) {
if s.ErrorCode != 0 {
Expand Down Expand Up @@ -141,10 +152,6 @@ func (s TestPackagingPluginServer) DeleteInstalledPackage(ctx context.Context, r
return connect.NewResponse(&corev1.DeleteInstalledPackageResponse{}), nil
}

func (s TestPackagingPluginServer) GetAvailablePackageMetadatas(ctx context.Context, request *connect.Request[corev1.GetAvailablePackageMetadatasRequest]) (*connect.Response[corev1.GetAvailablePackageMetadatasResponse], error) {
return nil, connect.NewError(connect.CodeUnimplemented, fmt.Errorf("Unimplemented"))
}

type TestRepositoriesPluginServer struct {
corev1.UnimplementedRepositoriesServiceServer
Plugin *plugins.Plugin
Expand Down
9 changes: 9 additions & 0 deletions cmd/kubeapps-apis/plugin_test/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,15 @@ func MakeAvailablePackageDetail(name string, plugin *plugins.Plugin) *corev1.Ava
}
}

func MakeAvailablePackageMetadata(media_type, name, description, url string) *corev1.PackageMetadata {
return &corev1.PackageMetadata{
MediaType: media_type,
Name: name,
Description: description,
Url: url,
}
}

func MakeInstalledPackageDetail(name string, plugin *plugins.Plugin) *corev1.InstalledPackageDetail {
return &corev1.InstalledPackageDetail{
InstalledPackageRef: &corev1.InstalledPackageReference{
Expand Down

0 comments on commit 559f82f

Please sign in to comment.