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

4th step for Investigate and propose package repositories API with similar core interface to packages API. #3496 #4573

Merged
33 changes: 33 additions & 0 deletions cmd/kubeapps-apis/core/packages/v1alpha1/repositories.go
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,39 @@ func (s repositoriesServer) GetPackageRepositorySummaries(ctx context.Context, r
}, nil
}

// UpdatePackageRepository updates a package repository using configured plugins.
func (s repositoriesServer) UpdatePackageRepository(ctx context.Context, request *packages.UpdatePackageRepositoryRequest) (*packages.UpdatePackageRepositoryResponse, error) {
contextMsg := fmt.Sprintf("(cluster=%q, namespace=%q, id=%q)",
request.GetPackageRepoRef().GetContext().GetCluster(),
request.GetPackageRepoRef().GetContext().GetNamespace(),
request.GetPackageRepoRef().GetIdentifier())
log.Infof("+core UpdatePackageRepository %s", contextMsg)

if request.GetPackageRepoRef().GetPlugin() == nil {
return nil, status.Errorf(codes.InvalidArgument, "Unable to retrieve the plugin (missing PackageRepoRef.Plugin)")
}

// Retrieve the plugin with server matching the requested plugin name
pluginWithServer := s.getPluginWithServer(request.PackageRepoRef.Plugin)
if pluginWithServer == nil {
return nil, status.Errorf(codes.Internal, "Unable to get the plugin %v", request.PackageRepoRef.Plugin)
}

// Get the response from the requested plugin
response, err := pluginWithServer.server.UpdatePackageRepository(ctx, request)
if err != nil {
return nil, status.Errorf(status.Convert(err).Code(), "Unable to update the package repository %q using the plugin %q: %v",
request.PackageRepoRef.Identifier, request.PackageRepoRef.Plugin.Name, err)
}

// Validate the plugin response
if response.PackageRepoRef == nil {
return nil, status.Errorf(codes.Internal, "Invalid UpdatePackageRepository response from the plugin %v: %v", pluginWithServer.plugin.Name, err)
}

return response, nil
}

// getPluginWithServer returns the *pkgPluginsWithServer from a given packagesServer
// matching the plugin name
func (s repositoriesServer) getPluginWithServer(plugin *v1alpha1.Plugin) *repoPluginsWithServer {
Expand Down
82 changes: 82 additions & 0 deletions cmd/kubeapps-apis/core/packages/v1alpha1/repositories_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ var ignoreUnexportedRepoOpts = cmpopts.IgnoreUnexported(
corev1.PackageRepositoryStatus{},
corev1.GetPackageRepositorySummariesResponse{},
corev1.PackageRepositorySummary{},
corev1.UpdatePackageRepositoryResponse{},
)

func makeDefaultTestRepositoriesPlugin(pluginName string) repoPluginsWithServer {
Expand Down Expand Up @@ -286,3 +287,84 @@ func TestGetPackageRepositorySummaries(t *testing.T) {
})
}
}

func TestUpdatePackageRepository(t *testing.T) {

testCases := []struct {
name string
configuredPlugins []*plugins.Plugin
statusCode codes.Code
request *corev1.UpdatePackageRepositoryRequest
expectedResponse *corev1.UpdatePackageRepositoryResponse
}{
{
name: "updates the package repository using the correct plugin",
configuredPlugins: []*plugins.Plugin{
{Name: "plugin-1", Version: "v1alpha1"},
{Name: "plugin-1", Version: "v1alpha2"},
},
statusCode: codes.OK,
request: &corev1.UpdatePackageRepositoryRequest{
PackageRepoRef: &corev1.PackageRepositoryReference{
Context: &corev1.Context{Cluster: "default", Namespace: "my-ns"},
Identifier: "repo-1",
Plugin: &plugins.Plugin{Name: "plugin-1", Version: "v1alpha1"},
},
},
expectedResponse: &corev1.UpdatePackageRepositoryResponse{
PackageRepoRef: &corev1.PackageRepositoryReference{
Context: &corev1.Context{Cluster: "default", Namespace: "my-ns"},
Identifier: "repo-1",
Plugin: &plugins.Plugin{Name: "plugin-1", Version: "v1alpha1"},
},
},
},
{
name: "returns invalid argument if plugin not specified in request",
statusCode: codes.InvalidArgument,
request: &corev1.UpdatePackageRepositoryRequest{
PackageRepoRef: &corev1.PackageRepositoryReference{
Identifier: "repo-1",
},
},
},
{
name: "returns internal error if unable to find the plugin",
statusCode: codes.Internal,
request: &corev1.UpdatePackageRepositoryRequest{
PackageRepoRef: &corev1.PackageRepositoryReference{
Identifier: "repo-1",
Plugin: &plugins.Plugin{Name: "plugin-1", Version: "v1alpha1"},
},
},
},
}

for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
configuredPluginServers := []repoPluginsWithServer{}
for _, p := range tc.configuredPlugins {
configuredPluginServers = append(configuredPluginServers, repoPluginsWithServer{
plugin: p,
server: plugin_test.TestRepositoriesPluginServer{Plugin: p},
})
}

server := &repositoriesServer{
pluginsWithServers: configuredPluginServers,
}

updatedRepoResponse, err := server.UpdatePackageRepository(context.Background(), tc.request)

if got, want := status.Code(err), tc.statusCode; got != want {
t.Fatalf("got: %+v, want: %+v, err: %+v", got, want, err)
}

if tc.statusCode == codes.OK {
if got, want := updatedRepoResponse, tc.expectedResponse; !cmp.Equal(got, want, ignoreUnexportedRepoOpts) {
t.Errorf("mismatch (-want +got):\n%s", cmp.Diff(want, got, ignoreUnexportedRepoOpts))
}
}
})
}
}
Loading