mirror of
https://github.com/vmware-tanzu/velero.git
synced 2026-01-03 11:45:20 +00:00
RestoreItemAction v2 API implementation
Signed-off-by: Scott Seago <sseago@redhat.com>
This commit is contained in:
@@ -29,6 +29,7 @@ import (
|
||||
biav2 "github.com/vmware-tanzu/velero/pkg/plugin/velero/backupitemaction/v2"
|
||||
isv1 "github.com/vmware-tanzu/velero/pkg/plugin/velero/item_snapshotter/v1"
|
||||
riav1 "github.com/vmware-tanzu/velero/pkg/plugin/velero/restoreitemaction/v1"
|
||||
riav2 "github.com/vmware-tanzu/velero/pkg/plugin/velero/restoreitemaction/v2"
|
||||
"github.com/vmware-tanzu/velero/pkg/util/collections"
|
||||
)
|
||||
|
||||
@@ -128,6 +129,12 @@ func NewRestoreItemActionResolver(actions []riav1.RestoreItemAction) RestoreItem
|
||||
}
|
||||
}
|
||||
|
||||
func NewRestoreItemActionResolverV2(actions []riav2.RestoreItemAction) RestoreItemActionResolverV2 {
|
||||
return RestoreItemActionResolverV2{
|
||||
actions: actions,
|
||||
}
|
||||
}
|
||||
|
||||
func NewDeleteItemActionResolver(actions []velero.DeleteItemAction) DeleteItemActionResolver {
|
||||
return DeleteItemActionResolver{
|
||||
actions: actions,
|
||||
@@ -199,6 +206,11 @@ type RestoreItemResolvedAction struct {
|
||||
resolvedAction
|
||||
}
|
||||
|
||||
type RestoreItemResolvedActionV2 struct {
|
||||
riav2.RestoreItemAction
|
||||
resolvedAction
|
||||
}
|
||||
|
||||
type RestoreItemActionResolver struct {
|
||||
actions []riav1.RestoreItemAction
|
||||
}
|
||||
@@ -223,6 +235,30 @@ func (recv RestoreItemActionResolver) ResolveActions(helper discovery.Helper, lo
|
||||
return resolved, nil
|
||||
}
|
||||
|
||||
type RestoreItemActionResolverV2 struct {
|
||||
actions []riav2.RestoreItemAction
|
||||
}
|
||||
|
||||
func (recv RestoreItemActionResolverV2) ResolveActions(helper discovery.Helper, log logrus.FieldLogger) ([]RestoreItemResolvedActionV2, error) {
|
||||
var resolved []RestoreItemResolvedActionV2
|
||||
for _, action := range recv.actions {
|
||||
resources, namespaces, selector, err := resolveAction(helper, action)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
res := RestoreItemResolvedActionV2{
|
||||
RestoreItemAction: action,
|
||||
resolvedAction: resolvedAction{
|
||||
ResourceIncludesExcludes: resources,
|
||||
NamespaceIncludesExcludes: namespaces,
|
||||
Selector: selector,
|
||||
},
|
||||
}
|
||||
resolved = append(resolved, res)
|
||||
}
|
||||
return resolved, nil
|
||||
}
|
||||
|
||||
type DeleteItemResolvedAction struct {
|
||||
velero.DeleteItemAction
|
||||
resolvedAction
|
||||
|
||||
@@ -41,6 +41,9 @@ const (
|
||||
// PluginKindRestoreItemAction represents a restore item action plugin.
|
||||
PluginKindRestoreItemAction PluginKind = "RestoreItemAction"
|
||||
|
||||
// PluginKindRestoreItemAction represents a v2 restore item action plugin.
|
||||
PluginKindRestoreItemActionV2 PluginKind = "RestoreItemActionV2"
|
||||
|
||||
// PluginKindDeleteItemAction represents a delete item action plugin.
|
||||
PluginKindDeleteItemAction PluginKind = "DeleteItemAction"
|
||||
|
||||
@@ -55,7 +58,8 @@ const (
|
||||
// The older (adaptable) version is the key, and the value is the full list of newer
|
||||
// plugin kinds that are capable of adapting it.
|
||||
var PluginKindsAdaptableTo = map[PluginKind][]PluginKind{
|
||||
PluginKindBackupItemAction: {PluginKindBackupItemActionV2},
|
||||
PluginKindBackupItemAction: {PluginKindBackupItemActionV2},
|
||||
PluginKindRestoreItemAction: {PluginKindRestoreItemActionV2},
|
||||
}
|
||||
|
||||
// AllPluginKinds contains all the valid plugin kinds that Velero supports, excluding PluginLister because that is not a
|
||||
@@ -67,6 +71,7 @@ func AllPluginKinds() map[string]PluginKind {
|
||||
allPluginKinds[PluginKindBackupItemAction.String()] = PluginKindBackupItemAction
|
||||
allPluginKinds[PluginKindBackupItemActionV2.String()] = PluginKindBackupItemActionV2
|
||||
allPluginKinds[PluginKindRestoreItemAction.String()] = PluginKindRestoreItemAction
|
||||
allPluginKinds[PluginKindRestoreItemActionV2.String()] = PluginKindRestoreItemActionV2
|
||||
allPluginKinds[PluginKindDeleteItemAction.String()] = PluginKindDeleteItemAction
|
||||
allPluginKinds[PluginKindItemSnapshotter.String()] = PluginKindItemSnapshotter
|
||||
return allPluginKinds
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
Copyright the Velero contributors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package v2
|
||||
|
||||
import (
|
||||
plugin "github.com/hashicorp/go-plugin"
|
||||
"golang.org/x/net/context"
|
||||
"google.golang.org/grpc"
|
||||
|
||||
"github.com/vmware-tanzu/velero/pkg/plugin/framework/common"
|
||||
protoriav2 "github.com/vmware-tanzu/velero/pkg/plugin/generated/restoreitemaction/v2"
|
||||
)
|
||||
|
||||
// RestoreItemActionPlugin is an implementation of go-plugin's Plugin
|
||||
// interface with support for gRPC for the restore/ItemAction
|
||||
// interface.
|
||||
type RestoreItemActionPlugin struct {
|
||||
plugin.NetRPCUnsupportedPlugin
|
||||
*common.PluginBase
|
||||
}
|
||||
|
||||
// GRPCClient returns a RestoreItemAction gRPC client.
|
||||
func (p *RestoreItemActionPlugin) GRPCClient(_ context.Context, _ *plugin.GRPCBroker, clientConn *grpc.ClientConn) (interface{}, error) {
|
||||
return common.NewClientDispenser(p.ClientLogger, clientConn, newRestoreItemActionGRPCClient), nil
|
||||
}
|
||||
|
||||
// GRPCServer registers a RestoreItemAction gRPC server.
|
||||
func (p *RestoreItemActionPlugin) GRPCServer(_ *plugin.GRPCBroker, server *grpc.Server) error {
|
||||
protoriav2.RegisterRestoreItemActionServer(server, &RestoreItemActionGRPCServer{mux: p.ServerMux})
|
||||
return nil
|
||||
}
|
||||
@@ -0,0 +1,201 @@
|
||||
/*
|
||||
Copyright the Velero contributors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package v2
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"golang.org/x/net/context"
|
||||
"google.golang.org/grpc"
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
|
||||
api "github.com/vmware-tanzu/velero/pkg/apis/velero/v1"
|
||||
"github.com/vmware-tanzu/velero/pkg/plugin/framework/common"
|
||||
protoriav2 "github.com/vmware-tanzu/velero/pkg/plugin/generated/restoreitemaction/v2"
|
||||
"github.com/vmware-tanzu/velero/pkg/plugin/velero"
|
||||
riav2 "github.com/vmware-tanzu/velero/pkg/plugin/velero/restoreitemaction/v2"
|
||||
)
|
||||
|
||||
var _ riav2.RestoreItemAction = &RestoreItemActionGRPCClient{}
|
||||
|
||||
// NewRestoreItemActionPlugin constructs a RestoreItemActionPlugin.
|
||||
func NewRestoreItemActionPlugin(options ...common.PluginOption) *RestoreItemActionPlugin {
|
||||
return &RestoreItemActionPlugin{
|
||||
PluginBase: common.NewPluginBase(options...),
|
||||
}
|
||||
}
|
||||
|
||||
// RestoreItemActionGRPCClient implements the backup/ItemAction interface and uses a
|
||||
// gRPC client to make calls to the plugin server.
|
||||
type RestoreItemActionGRPCClient struct {
|
||||
*common.ClientBase
|
||||
grpcClient protoriav2.RestoreItemActionClient
|
||||
}
|
||||
|
||||
func newRestoreItemActionGRPCClient(base *common.ClientBase, clientConn *grpc.ClientConn) interface{} {
|
||||
return &RestoreItemActionGRPCClient{
|
||||
ClientBase: base,
|
||||
grpcClient: protoriav2.NewRestoreItemActionClient(clientConn),
|
||||
}
|
||||
}
|
||||
|
||||
func (c *RestoreItemActionGRPCClient) AppliesTo() (velero.ResourceSelector, error) {
|
||||
res, err := c.grpcClient.AppliesTo(context.Background(), &protoriav2.RestoreItemActionAppliesToRequest{Plugin: c.Plugin})
|
||||
if err != nil {
|
||||
return velero.ResourceSelector{}, common.FromGRPCError(err)
|
||||
}
|
||||
|
||||
if res.ResourceSelector == nil {
|
||||
return velero.ResourceSelector{}, nil
|
||||
}
|
||||
|
||||
return velero.ResourceSelector{
|
||||
IncludedNamespaces: res.ResourceSelector.IncludedNamespaces,
|
||||
ExcludedNamespaces: res.ResourceSelector.ExcludedNamespaces,
|
||||
IncludedResources: res.ResourceSelector.IncludedResources,
|
||||
ExcludedResources: res.ResourceSelector.ExcludedResources,
|
||||
LabelSelector: res.ResourceSelector.Selector,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (c *RestoreItemActionGRPCClient) Execute(input *velero.RestoreItemActionExecuteInput) (*velero.RestoreItemActionExecuteOutput, error) {
|
||||
itemJSON, err := json.Marshal(input.Item.UnstructuredContent())
|
||||
if err != nil {
|
||||
return nil, errors.WithStack(err)
|
||||
}
|
||||
|
||||
itemFromBackupJSON, err := json.Marshal(input.ItemFromBackup.UnstructuredContent())
|
||||
if err != nil {
|
||||
return nil, errors.WithStack(err)
|
||||
}
|
||||
|
||||
restoreJSON, err := json.Marshal(input.Restore)
|
||||
if err != nil {
|
||||
return nil, errors.WithStack(err)
|
||||
}
|
||||
|
||||
req := &protoriav2.RestoreItemActionExecuteRequest{
|
||||
Plugin: c.Plugin,
|
||||
Item: itemJSON,
|
||||
ItemFromBackup: itemFromBackupJSON,
|
||||
Restore: restoreJSON,
|
||||
}
|
||||
|
||||
res, err := c.grpcClient.Execute(context.Background(), req)
|
||||
if err != nil {
|
||||
return nil, common.FromGRPCError(err)
|
||||
}
|
||||
|
||||
var updatedItem unstructured.Unstructured
|
||||
if err := json.Unmarshal(res.Item, &updatedItem); err != nil {
|
||||
return nil, errors.WithStack(err)
|
||||
}
|
||||
|
||||
var additionalItems []velero.ResourceIdentifier
|
||||
for _, itm := range res.AdditionalItems {
|
||||
newItem := velero.ResourceIdentifier{
|
||||
GroupResource: schema.GroupResource{
|
||||
Group: itm.Group,
|
||||
Resource: itm.Resource,
|
||||
},
|
||||
Namespace: itm.Namespace,
|
||||
Name: itm.Name,
|
||||
}
|
||||
|
||||
additionalItems = append(additionalItems, newItem)
|
||||
}
|
||||
|
||||
return &velero.RestoreItemActionExecuteOutput{
|
||||
UpdatedItem: &updatedItem,
|
||||
AdditionalItems: additionalItems,
|
||||
SkipRestore: res.SkipRestore,
|
||||
OperationID: res.OperationID,
|
||||
WaitForAdditionalItems: res.WaitForAdditionalItems,
|
||||
AdditionalItemsReadyTimeout: res.AdditionalItemsReadyTimeout.AsDuration(),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (c *RestoreItemActionGRPCClient) Progress(operationID string, restore *api.Restore) (velero.OperationProgress, error) {
|
||||
restoreJSON, err := json.Marshal(restore)
|
||||
if err != nil {
|
||||
return velero.OperationProgress{}, errors.WithStack(err)
|
||||
}
|
||||
req := &protoriav2.RestoreItemActionProgressRequest{
|
||||
Plugin: c.Plugin,
|
||||
OperationID: operationID,
|
||||
Restore: restoreJSON,
|
||||
}
|
||||
|
||||
res, err := c.grpcClient.Progress(context.Background(), req)
|
||||
if err != nil {
|
||||
return velero.OperationProgress{}, common.FromGRPCError(err)
|
||||
}
|
||||
|
||||
return velero.OperationProgress{
|
||||
Completed: res.Progress.Completed,
|
||||
Err: res.Progress.Err,
|
||||
NCompleted: res.Progress.NCompleted,
|
||||
NTotal: res.Progress.NTotal,
|
||||
OperationUnits: res.Progress.OperationUnits,
|
||||
Description: res.Progress.Description,
|
||||
Started: res.Progress.Started.AsTime(),
|
||||
Updated: res.Progress.Updated.AsTime(),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (c *RestoreItemActionGRPCClient) Cancel(operationID string, restore *api.Restore) error {
|
||||
restoreJSON, err := json.Marshal(restore)
|
||||
if err != nil {
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
req := &protoriav2.RestoreItemActionCancelRequest{
|
||||
Plugin: c.Plugin,
|
||||
OperationID: operationID,
|
||||
Restore: restoreJSON,
|
||||
}
|
||||
|
||||
_, err = c.grpcClient.Cancel(context.Background(), req)
|
||||
if err != nil {
|
||||
return common.FromGRPCError(err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *RestoreItemActionGRPCClient) AreAdditionalItemsReady(additionalItems []velero.ResourceIdentifier, restore *api.Restore) (bool, error) {
|
||||
restoreJSON, err := json.Marshal(restore)
|
||||
if err != nil {
|
||||
return false, errors.WithStack(err)
|
||||
}
|
||||
|
||||
req := &protoriav2.RestoreItemActionItemsReadyRequest{
|
||||
Plugin: c.Plugin,
|
||||
Restore: restoreJSON,
|
||||
}
|
||||
for _, item := range additionalItems {
|
||||
req.AdditionalItems = append(req.AdditionalItems, restoreResourceIdentifierToProto(item))
|
||||
}
|
||||
|
||||
res, err := c.grpcClient.AreAdditionalItemsReady(context.Background(), req)
|
||||
if err != nil {
|
||||
return false, common.FromGRPCError(err)
|
||||
}
|
||||
|
||||
return res.Ready, nil
|
||||
}
|
||||
@@ -0,0 +1,265 @@
|
||||
/*
|
||||
Copyright the Velero contributors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package v2
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"golang.org/x/net/context"
|
||||
"google.golang.org/protobuf/types/known/durationpb"
|
||||
"google.golang.org/protobuf/types/known/emptypb"
|
||||
"google.golang.org/protobuf/types/known/timestamppb"
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
|
||||
api "github.com/vmware-tanzu/velero/pkg/apis/velero/v1"
|
||||
"github.com/vmware-tanzu/velero/pkg/plugin/framework/common"
|
||||
proto "github.com/vmware-tanzu/velero/pkg/plugin/generated"
|
||||
protoriav2 "github.com/vmware-tanzu/velero/pkg/plugin/generated/restoreitemaction/v2"
|
||||
"github.com/vmware-tanzu/velero/pkg/plugin/velero"
|
||||
riav2 "github.com/vmware-tanzu/velero/pkg/plugin/velero/restoreitemaction/v2"
|
||||
)
|
||||
|
||||
// RestoreItemActionGRPCServer implements the proto-generated RestoreItemActionServer interface, and accepts
|
||||
// gRPC calls and forwards them to an implementation of the pluggable interface.
|
||||
type RestoreItemActionGRPCServer struct {
|
||||
mux *common.ServerMux
|
||||
}
|
||||
|
||||
func (s *RestoreItemActionGRPCServer) getImpl(name string) (riav2.RestoreItemAction, error) {
|
||||
impl, err := s.mux.GetHandler(name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
itemAction, ok := impl.(riav2.RestoreItemAction)
|
||||
if !ok {
|
||||
return nil, errors.Errorf("%T is not a restore item action (v2)", impl)
|
||||
}
|
||||
|
||||
return itemAction, nil
|
||||
}
|
||||
|
||||
func (s *RestoreItemActionGRPCServer) AppliesTo(ctx context.Context, req *protoriav2.RestoreItemActionAppliesToRequest) (response *protoriav2.RestoreItemActionAppliesToResponse, err error) {
|
||||
defer func() {
|
||||
if recoveredErr := common.HandlePanic(recover()); recoveredErr != nil {
|
||||
err = recoveredErr
|
||||
}
|
||||
}()
|
||||
|
||||
impl, err := s.getImpl(req.Plugin)
|
||||
if err != nil {
|
||||
return nil, common.NewGRPCError(err)
|
||||
}
|
||||
|
||||
resourceSelector, err := impl.AppliesTo()
|
||||
if err != nil {
|
||||
return nil, common.NewGRPCError(err)
|
||||
}
|
||||
|
||||
return &protoriav2.RestoreItemActionAppliesToResponse{
|
||||
ResourceSelector: &proto.ResourceSelector{
|
||||
IncludedNamespaces: resourceSelector.IncludedNamespaces,
|
||||
ExcludedNamespaces: resourceSelector.ExcludedNamespaces,
|
||||
IncludedResources: resourceSelector.IncludedResources,
|
||||
ExcludedResources: resourceSelector.ExcludedResources,
|
||||
Selector: resourceSelector.LabelSelector,
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (s *RestoreItemActionGRPCServer) Execute(ctx context.Context, req *protoriav2.RestoreItemActionExecuteRequest) (response *protoriav2.RestoreItemActionExecuteResponse, err error) {
|
||||
defer func() {
|
||||
if recoveredErr := common.HandlePanic(recover()); recoveredErr != nil {
|
||||
err = recoveredErr
|
||||
}
|
||||
}()
|
||||
|
||||
impl, err := s.getImpl(req.Plugin)
|
||||
if err != nil {
|
||||
return nil, common.NewGRPCError(err)
|
||||
}
|
||||
|
||||
var (
|
||||
item unstructured.Unstructured
|
||||
itemFromBackup unstructured.Unstructured
|
||||
restoreObj api.Restore
|
||||
)
|
||||
|
||||
if err := json.Unmarshal(req.Item, &item); err != nil {
|
||||
return nil, common.NewGRPCError(errors.WithStack(err))
|
||||
}
|
||||
|
||||
if err := json.Unmarshal(req.ItemFromBackup, &itemFromBackup); err != nil {
|
||||
return nil, common.NewGRPCError(errors.WithStack(err))
|
||||
}
|
||||
|
||||
if err := json.Unmarshal(req.Restore, &restoreObj); err != nil {
|
||||
return nil, common.NewGRPCError(errors.WithStack(err))
|
||||
}
|
||||
|
||||
executeOutput, err := impl.Execute(&velero.RestoreItemActionExecuteInput{
|
||||
Item: &item,
|
||||
ItemFromBackup: &itemFromBackup,
|
||||
Restore: &restoreObj,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, common.NewGRPCError(err)
|
||||
}
|
||||
|
||||
// If the plugin implementation returned a nil updateItem (meaning no modifications), reset updatedItem to the
|
||||
// original item.
|
||||
var updatedItemJSON []byte
|
||||
if executeOutput.UpdatedItem == nil {
|
||||
updatedItemJSON = req.Item
|
||||
} else {
|
||||
updatedItemJSON, err = json.Marshal(executeOutput.UpdatedItem.UnstructuredContent())
|
||||
if err != nil {
|
||||
return nil, common.NewGRPCError(errors.WithStack(err))
|
||||
}
|
||||
}
|
||||
|
||||
res := &protoriav2.RestoreItemActionExecuteResponse{
|
||||
Item: updatedItemJSON,
|
||||
SkipRestore: executeOutput.SkipRestore,
|
||||
OperationID: executeOutput.OperationID,
|
||||
WaitForAdditionalItems: executeOutput.WaitForAdditionalItems,
|
||||
AdditionalItemsReadyTimeout: durationpb.New(executeOutput.AdditionalItemsReadyTimeout),
|
||||
}
|
||||
|
||||
for _, item := range executeOutput.AdditionalItems {
|
||||
res.AdditionalItems = append(res.AdditionalItems, restoreResourceIdentifierToProto(item))
|
||||
}
|
||||
|
||||
return res, nil
|
||||
}
|
||||
|
||||
func (s *RestoreItemActionGRPCServer) Progress(ctx context.Context, req *protoriav2.RestoreItemActionProgressRequest) (
|
||||
response *protoriav2.RestoreItemActionProgressResponse, err error) {
|
||||
defer func() {
|
||||
if recoveredErr := common.HandlePanic(recover()); recoveredErr != nil {
|
||||
err = recoveredErr
|
||||
}
|
||||
}()
|
||||
|
||||
impl, err := s.getImpl(req.Plugin)
|
||||
if err != nil {
|
||||
return nil, common.NewGRPCError(err)
|
||||
}
|
||||
|
||||
var restore api.Restore
|
||||
if err := json.Unmarshal(req.Restore, &restore); err != nil {
|
||||
return nil, common.NewGRPCError(errors.WithStack(err))
|
||||
}
|
||||
|
||||
progress, err := impl.Progress(req.OperationID, &restore)
|
||||
if err != nil {
|
||||
return nil, common.NewGRPCError(err)
|
||||
}
|
||||
|
||||
res := &protoriav2.RestoreItemActionProgressResponse{
|
||||
Progress: &proto.OperationProgress{
|
||||
Completed: progress.Completed,
|
||||
Err: progress.Err,
|
||||
NCompleted: progress.NCompleted,
|
||||
NTotal: progress.NTotal,
|
||||
OperationUnits: progress.OperationUnits,
|
||||
Description: progress.Description,
|
||||
Started: timestamppb.New(progress.Started),
|
||||
Updated: timestamppb.New(progress.Updated),
|
||||
},
|
||||
}
|
||||
return res, nil
|
||||
}
|
||||
|
||||
func (s *RestoreItemActionGRPCServer) Cancel(
|
||||
ctx context.Context, req *protoriav2.RestoreItemActionCancelRequest) (
|
||||
response *emptypb.Empty, err error) {
|
||||
defer func() {
|
||||
if recoveredErr := common.HandlePanic(recover()); recoveredErr != nil {
|
||||
err = recoveredErr
|
||||
}
|
||||
}()
|
||||
|
||||
impl, err := s.getImpl(req.Plugin)
|
||||
if err != nil {
|
||||
return nil, common.NewGRPCError(err)
|
||||
}
|
||||
|
||||
var restore api.Restore
|
||||
if err := json.Unmarshal(req.Restore, &restore); err != nil {
|
||||
return nil, common.NewGRPCError(errors.WithStack(err))
|
||||
}
|
||||
|
||||
err = impl.Cancel(req.OperationID, &restore)
|
||||
if err != nil {
|
||||
return nil, common.NewGRPCError(err)
|
||||
}
|
||||
|
||||
return &emptypb.Empty{}, nil
|
||||
}
|
||||
|
||||
func (s *RestoreItemActionGRPCServer) AreAdditionalItemsReady(ctx context.Context, req *protoriav2.RestoreItemActionItemsReadyRequest) (
|
||||
response *protoriav2.RestoreItemActionItemsReadyResponse, err error) {
|
||||
defer func() {
|
||||
if recoveredErr := common.HandlePanic(recover()); recoveredErr != nil {
|
||||
err = recoveredErr
|
||||
}
|
||||
}()
|
||||
|
||||
impl, err := s.getImpl(req.Plugin)
|
||||
if err != nil {
|
||||
return nil, common.NewGRPCError(err)
|
||||
}
|
||||
|
||||
var restore api.Restore
|
||||
if err := json.Unmarshal(req.Restore, &restore); err != nil {
|
||||
return nil, common.NewGRPCError(errors.WithStack(err))
|
||||
}
|
||||
var additionalItems []velero.ResourceIdentifier
|
||||
for _, itm := range req.AdditionalItems {
|
||||
newItem := velero.ResourceIdentifier{
|
||||
GroupResource: schema.GroupResource{
|
||||
Group: itm.Group,
|
||||
Resource: itm.Resource,
|
||||
},
|
||||
Namespace: itm.Namespace,
|
||||
Name: itm.Name,
|
||||
}
|
||||
|
||||
additionalItems = append(additionalItems, newItem)
|
||||
}
|
||||
ready, err := impl.AreAdditionalItemsReady(additionalItems, &restore)
|
||||
if err != nil {
|
||||
return nil, common.NewGRPCError(err)
|
||||
}
|
||||
|
||||
res := &protoriav2.RestoreItemActionItemsReadyResponse{
|
||||
Ready: ready,
|
||||
}
|
||||
return res, nil
|
||||
}
|
||||
|
||||
func restoreResourceIdentifierToProto(id velero.ResourceIdentifier) *proto.ResourceIdentifier {
|
||||
return &proto.ResourceIdentifier{
|
||||
Group: id.Group,
|
||||
Resource: id.Resource,
|
||||
Namespace: id.Namespace,
|
||||
Name: id.Name,
|
||||
}
|
||||
}
|
||||
@@ -27,6 +27,7 @@ import (
|
||||
|
||||
biav2 "github.com/vmware-tanzu/velero/pkg/plugin/framework/backupitemaction/v2"
|
||||
"github.com/vmware-tanzu/velero/pkg/plugin/framework/common"
|
||||
riav2 "github.com/vmware-tanzu/velero/pkg/plugin/framework/restoreitemaction/v2"
|
||||
"github.com/vmware-tanzu/velero/pkg/util/logging"
|
||||
)
|
||||
|
||||
@@ -75,6 +76,13 @@ type Server interface {
|
||||
// RegisterRestoreItemActions registers multiple restore item actions.
|
||||
RegisterRestoreItemActions(map[string]common.HandlerInitializer) Server
|
||||
|
||||
// RegisterRestoreItemActionV2 registers a v2 restore item action. Accepted format
|
||||
// for the plugin name is <DNS subdomain>/<non-empty name>.
|
||||
RegisterRestoreItemActionV2(pluginName string, initializer common.HandlerInitializer) Server
|
||||
|
||||
// RegisterRestoreItemActionsV2 registers multiple v2 restore item actions.
|
||||
RegisterRestoreItemActionsV2(map[string]common.HandlerInitializer) Server
|
||||
|
||||
// RegisterDeleteItemAction registers a delete item action. Accepted format
|
||||
// for the plugin name is <DNS subdomain>/<non-empty name>.
|
||||
RegisterDeleteItemAction(pluginName string, initializer common.HandlerInitializer) Server
|
||||
@@ -93,16 +101,17 @@ type Server interface {
|
||||
|
||||
// server implements Server.
|
||||
type server struct {
|
||||
log *logrus.Logger
|
||||
logLevelFlag *logging.LevelFlag
|
||||
flagSet *pflag.FlagSet
|
||||
backupItemAction *BackupItemActionPlugin
|
||||
backupItemActionV2 *biav2.BackupItemActionPlugin
|
||||
volumeSnapshotter *VolumeSnapshotterPlugin
|
||||
objectStore *ObjectStorePlugin
|
||||
restoreItemAction *RestoreItemActionPlugin
|
||||
deleteItemAction *DeleteItemActionPlugin
|
||||
itemSnapshotter *ItemSnapshotterPlugin
|
||||
log *logrus.Logger
|
||||
logLevelFlag *logging.LevelFlag
|
||||
flagSet *pflag.FlagSet
|
||||
backupItemAction *BackupItemActionPlugin
|
||||
backupItemActionV2 *biav2.BackupItemActionPlugin
|
||||
volumeSnapshotter *VolumeSnapshotterPlugin
|
||||
objectStore *ObjectStorePlugin
|
||||
restoreItemAction *RestoreItemActionPlugin
|
||||
restoreItemActionV2 *riav2.RestoreItemActionPlugin
|
||||
deleteItemAction *DeleteItemActionPlugin
|
||||
itemSnapshotter *ItemSnapshotterPlugin
|
||||
}
|
||||
|
||||
// NewServer returns a new Server
|
||||
@@ -110,15 +119,16 @@ func NewServer() Server {
|
||||
log := newLogger()
|
||||
|
||||
return &server{
|
||||
log: log,
|
||||
logLevelFlag: logging.LogLevelFlag(log.Level),
|
||||
backupItemAction: NewBackupItemActionPlugin(common.ServerLogger(log)),
|
||||
backupItemActionV2: biav2.NewBackupItemActionPlugin(common.ServerLogger(log)),
|
||||
volumeSnapshotter: NewVolumeSnapshotterPlugin(common.ServerLogger(log)),
|
||||
objectStore: NewObjectStorePlugin(common.ServerLogger(log)),
|
||||
restoreItemAction: NewRestoreItemActionPlugin(common.ServerLogger(log)),
|
||||
deleteItemAction: NewDeleteItemActionPlugin(common.ServerLogger(log)),
|
||||
itemSnapshotter: NewItemSnapshotterPlugin(common.ServerLogger(log)),
|
||||
log: log,
|
||||
logLevelFlag: logging.LogLevelFlag(log.Level),
|
||||
backupItemAction: NewBackupItemActionPlugin(common.ServerLogger(log)),
|
||||
backupItemActionV2: biav2.NewBackupItemActionPlugin(common.ServerLogger(log)),
|
||||
volumeSnapshotter: NewVolumeSnapshotterPlugin(common.ServerLogger(log)),
|
||||
objectStore: NewObjectStorePlugin(common.ServerLogger(log)),
|
||||
restoreItemAction: NewRestoreItemActionPlugin(common.ServerLogger(log)),
|
||||
restoreItemActionV2: riav2.NewRestoreItemActionPlugin(common.ServerLogger(log)),
|
||||
deleteItemAction: NewDeleteItemActionPlugin(common.ServerLogger(log)),
|
||||
itemSnapshotter: NewItemSnapshotterPlugin(common.ServerLogger(log)),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -190,6 +200,18 @@ func (s *server) RegisterRestoreItemActions(m map[string]common.HandlerInitializ
|
||||
return s
|
||||
}
|
||||
|
||||
func (s *server) RegisterRestoreItemActionV2(name string, initializer common.HandlerInitializer) Server {
|
||||
s.restoreItemActionV2.Register(name, initializer)
|
||||
return s
|
||||
}
|
||||
|
||||
func (s *server) RegisterRestoreItemActionsV2(m map[string]common.HandlerInitializer) Server {
|
||||
for name := range m {
|
||||
s.RegisterRestoreItemActionV2(name, m[name])
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
func (s *server) RegisterDeleteItemAction(name string, initializer common.HandlerInitializer) Server {
|
||||
s.deleteItemAction.Register(name, initializer)
|
||||
return s
|
||||
@@ -242,6 +264,7 @@ func (s *server) Serve() {
|
||||
pluginIdentifiers = append(pluginIdentifiers, getNames(command, common.PluginKindVolumeSnapshotter, s.volumeSnapshotter)...)
|
||||
pluginIdentifiers = append(pluginIdentifiers, getNames(command, common.PluginKindObjectStore, s.objectStore)...)
|
||||
pluginIdentifiers = append(pluginIdentifiers, getNames(command, common.PluginKindRestoreItemAction, s.restoreItemAction)...)
|
||||
pluginIdentifiers = append(pluginIdentifiers, getNames(command, common.PluginKindRestoreItemActionV2, s.restoreItemActionV2)...)
|
||||
pluginIdentifiers = append(pluginIdentifiers, getNames(command, common.PluginKindDeleteItemAction, s.deleteItemAction)...)
|
||||
pluginIdentifiers = append(pluginIdentifiers, getNames(command, common.PluginKindItemSnapshotter, s.itemSnapshotter)...)
|
||||
|
||||
@@ -250,14 +273,15 @@ func (s *server) Serve() {
|
||||
plugin.Serve(&plugin.ServeConfig{
|
||||
HandshakeConfig: Handshake(),
|
||||
Plugins: map[string]plugin.Plugin{
|
||||
string(common.PluginKindBackupItemAction): s.backupItemAction,
|
||||
string(common.PluginKindBackupItemActionV2): s.backupItemActionV2,
|
||||
string(common.PluginKindVolumeSnapshotter): s.volumeSnapshotter,
|
||||
string(common.PluginKindObjectStore): s.objectStore,
|
||||
string(common.PluginKindPluginLister): NewPluginListerPlugin(pluginLister),
|
||||
string(common.PluginKindRestoreItemAction): s.restoreItemAction,
|
||||
string(common.PluginKindDeleteItemAction): s.deleteItemAction,
|
||||
string(common.PluginKindItemSnapshotter): s.itemSnapshotter,
|
||||
string(common.PluginKindBackupItemAction): s.backupItemAction,
|
||||
string(common.PluginKindBackupItemActionV2): s.backupItemActionV2,
|
||||
string(common.PluginKindVolumeSnapshotter): s.volumeSnapshotter,
|
||||
string(common.PluginKindObjectStore): s.objectStore,
|
||||
string(common.PluginKindPluginLister): NewPluginListerPlugin(pluginLister),
|
||||
string(common.PluginKindRestoreItemAction): s.restoreItemAction,
|
||||
string(common.PluginKindRestoreItemActionV2): s.restoreItemActionV2,
|
||||
string(common.PluginKindDeleteItemAction): s.deleteItemAction,
|
||||
string(common.PluginKindItemSnapshotter): s.itemSnapshotter,
|
||||
},
|
||||
GRPCServer: plugin.DefaultGRPCServer,
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user