Skip to content

Commit

Permalink
Merge pull request vmware-tanzu#4028 from zubron/add-restore-item-act…
Browse files Browse the repository at this point in the history
…ion-to-skip-automanaged-apiservices

Skip restore of APIServices managed by Kubernetes
  • Loading branch information
sseago authored and zubron committed Aug 12, 2021
1 parent b090b27 commit 6feb84a
Show file tree
Hide file tree
Showing 7 changed files with 136 additions and 2 deletions.
1 change: 1 addition & 0 deletions changelogs/unreleased/4028-zubron
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Add a RestoreItemAction plugin (`velero.io/apiservice`) which skips the restore of any `APIService` which is managed by Kubernetes. These are identified using the `kube-aggregator.kubernetes.io/automanaged` label.
3 changes: 3 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,9 @@ require (
k8s.io/cli-runtime v0.19.12
k8s.io/client-go v0.19.12
k8s.io/klog v1.0.0
k8s.io/klog/v2 v2.3.0 // indirect
k8s.io/kube-aggregator v0.19.12
k8s.io/utils v0.0.0-20201005171033-6301aaf42dc7 // indirect
sigs.k8s.io/cluster-api v0.3.11-0.20210106212952-b6c1b5b3db3d
sigs.k8s.io/controller-runtime v0.7.1-0.20201215171748-096b2e07c091
)
Expand Down
7 changes: 6 additions & 1 deletion go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -859,14 +859,19 @@ k8s.io/klog v1.0.0/go.mod h1:4Bi6QPql/J/LkTDqv7R/cd3hPo4k2DG6Ptcz060Ez5I=
k8s.io/klog/v2 v2.0.0/go.mod h1:PBfzABfn139FHAV07az/IF9Wp1bkk3vpT2XSJ76fSDE=
k8s.io/klog/v2 v2.2.0 h1:XRvcwJozkgZ1UQJmfMGpvRthQHOvihEhYtDfAaxMz/A=
k8s.io/klog/v2 v2.2.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y=
k8s.io/klog/v2 v2.3.0 h1:WmkrnW7fdrm0/DMClc+HIxtftvxVIPAhlVwMQo5yLco=
k8s.io/klog/v2 v2.3.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y=
k8s.io/kube-aggregator v0.19.12 h1:OwyNUe/7/gxzEnaLd3sC9Yrpx0fZAERzvFslX5Qq5g8=
k8s.io/kube-aggregator v0.19.12/go.mod h1:K76wPd03pSHEmS1FgJOcpryac5C3va4cbCvSu+4EmE0=
k8s.io/kube-openapi v0.0.0-20200410145947-61e04a5be9a6/go.mod h1:GRQhZsXIAJ1xR0C9bd8UpWHZ5plfAS9fzPjJuQ6JL3E=
k8s.io/kube-openapi v0.0.0-20200805222855-6aeccd4b50c6 h1:+WnxoVtG8TMiudHBSEtrVL1egv36TkkJm+bA8AxicmQ=
k8s.io/kube-openapi v0.0.0-20200805222855-6aeccd4b50c6/go.mod h1:UuqjUnNftUyPE5H64/qeyjQoUZhGpeFDVdxjTeEVN2o=
k8s.io/kubectl v0.19.2/go.mod h1:4ib3oj5ma6gF95QukTvC7ZBMxp60+UEAhDPjLuBIrV4=
k8s.io/metrics v0.19.2/go.mod h1:IlLaAGXN0q7yrtB+SV0q3JIraf6VtlDr+iuTcX21fCU=
k8s.io/utils v0.0.0-20200729134348-d5654de09c73/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA=
k8s.io/utils v0.0.0-20200912215256-4140de9c8800 h1:9ZNvfPvVIEsp/T1ez4GQuzCcCTEQWhovSofhqR73A6g=
k8s.io/utils v0.0.0-20200912215256-4140de9c8800/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA=
k8s.io/utils v0.0.0-20201005171033-6301aaf42dc7 h1:XQ0OMFdRDkDIu0b1zqEKSZdWUD7I4bZ4d4nqr8CLKbQ=
k8s.io/utils v0.0.0-20201005171033-6301aaf42dc7/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA=
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.9/go.mod h1:dzAXnQbTRyDlZPJX2SUPEqvnB+j7AJjtlox7PEwigU0=
sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.15/go.mod h1:LEScyzhFmoF5pso/YSeBstl57mOzx9xlU9n85RGrDQg=
Expand Down
5 changes: 5 additions & 0 deletions pkg/cmd/server/plugin/plugin.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ func NewCommand(f client.Factory) *cobra.Command {
RegisterRestoreItemAction("velero.io/cluster-role-bindings", newClusterRoleBindingItemAction).
RegisterRestoreItemAction("velero.io/crd-preserve-fields", newCRDV1PreserveUnknownFieldsItemAction).
RegisterRestoreItemAction("velero.io/change-pvc-node-selector", newChangePVCNodeSelectorItemAction(f)).
RegisterRestoreItemAction("velero.io/apiservice", newAPIServiceRestoreItemAction).
Serve()
},
}
Expand Down Expand Up @@ -197,3 +198,7 @@ func newChangePVCNodeSelectorItemAction(f client.Factory) veleroplugin.HandlerIn
), nil
}
}

func newAPIServiceRestoreItemAction(logger logrus.FieldLogger) (interface{}, error) {
return restore.NewAPIServiceAction(logger), nil
}
51 changes: 51 additions & 0 deletions pkg/restore/apiservice_action.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
/*
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 restore

import (
"github.com/sirupsen/logrus"
"k8s.io/kube-aggregator/pkg/controllers/autoregister"

"github.com/vmware-tanzu/velero/pkg/plugin/velero"
)

type APIServiceAction struct {
logger logrus.FieldLogger
}

// NewAPIServiceAction returns an APIServiceAction which is a RestoreItemAction plugin
// that will skip the restore of any APIServices which are managed by Kubernetes. This
// is determined by looking for the "kube-aggregator.kubernetes.io/automanaged" label on
// the APIService.
func NewAPIServiceAction(logger logrus.FieldLogger) *APIServiceAction {
return &APIServiceAction{logger: logger}
}

func (a *APIServiceAction) AppliesTo() (velero.ResourceSelector, error) {
return velero.ResourceSelector{
IncludedResources: []string{"apiservices"},
LabelSelector: autoregister.AutoRegisterManagedLabel,
}, nil
}

func (a *APIServiceAction) Execute(input *velero.RestoreItemActionExecuteInput) (*velero.RestoreItemActionExecuteOutput, error) {
a.logger.Info("Executing APIServiceAction")
defer a.logger.Info("Done executing APIServiceAction")

a.logger.Infof("Skipping restore of APIService as it is managed by Kubernetes")
return velero.NewRestoreItemActionExecuteOutput(input.Item).WithoutRestore(), nil
}
53 changes: 53 additions & 0 deletions pkg/restore/apiservice_action_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
/*
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 restore

import (
"testing"

"github.com/stretchr/testify/require"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/runtime"
apiregistrationv1 "k8s.io/kube-aggregator/pkg/apis/apiregistration/v1"

"github.com/vmware-tanzu/velero/pkg/plugin/velero"
velerotest "github.com/vmware-tanzu/velero/pkg/test"
)

func TestAPIServiceActionExecuteSkipsRestore(t *testing.T) {
obj := apiregistrationv1.APIService{
ObjectMeta: metav1.ObjectMeta{
Name: "v1.test.velero.io",
},
}

unstructuredAPIService, err := runtime.DefaultUnstructuredConverter.ToUnstructured(&obj)
require.NoError(t, err)

action := NewAPIServiceAction(velerotest.NewLogger())
res, err := action.Execute(&velero.RestoreItemActionExecuteInput{
Item: &unstructured.Unstructured{Object: unstructuredAPIService},
ItemFromBackup: &unstructured.Unstructured{Object: unstructuredAPIService},
})
require.NoError(t, err)

var apiService apiregistrationv1.APIService
require.NoError(t, runtime.DefaultUnstructuredConverter.FromUnstructured(res.UpdatedItem.UnstructuredContent(), &apiService))
require.Equal(t, obj, apiService)
require.Equal(t, true, res.SkipRestore)
}
18 changes: 17 additions & 1 deletion pkg/restore/restore_test.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
Copyright 2019 the Velero contributors.
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.
Expand Down Expand Up @@ -1139,6 +1139,22 @@ func TestRestoreActionsRunForCorrectItems(t *testing.T) {
new(recordResourcesAction).ForNamespace("ns-1").ForResource("pods"): {"ns-1/pod-1"},
},
},
{
name: "single action with a resource and label selector runs only for resources matching that label",
restore: defaultRestore().Result(),
backup: defaultBackup().Result(),
tarball: test.NewTarWriter(t).
AddItems("pods",
builder.ForPod("ns-1", "pod-1").ObjectMeta(builder.WithLabels("restore-resource", "true")).Result(),
builder.ForPod("ns-1", "pod-2").ObjectMeta(builder.WithLabels("do-not-restore-resource", "true")).Result(),
builder.ForPod("ns-2", "pod-1").Result(),
builder.ForPod("ns-2", "pod-2").ObjectMeta(builder.WithLabels("restore-resource")).Result(),
).Done(),
apiResources: []*test.APIResource{test.Pods()},
actions: map[*recordResourcesAction][]string{
new(recordResourcesAction).ForResource("pods").ForLabelSelector("restore-resource"): {"ns-1/pod-1", "ns-2/pod-2"},
},
},
{
name: "multiple actions, each with a different resource selector using short name, run for matching resources",
restore: defaultRestore().Result(),
Expand Down

0 comments on commit 6feb84a

Please sign in to comment.