Merge pull request #4030 from zubron/cherry-pick-apiservice-action-1-6-3

Cherry-pick and update changelog for v1.6.3
This commit is contained in:
Scott Seago
2021-08-11 21:43:26 -04:00
committed by GitHub
7 changed files with 136 additions and 2 deletions

View File

@@ -34,6 +34,7 @@ This API version was introduced in Kubernetes v1.8.
* Upgrade Velero ClusterRoleBinding to use v1 API (#3995, @jenting)
* Install Kubernetes preferred CRDs API version (v1beta1/v1). (#3999, @jenting)
* Use the cluster preferred CRD API version when polling for Velero CRD readiness. (#4015, @zubron)
* 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. (#4028, @zubron)
## v1.6.2
### 2021-07-16

3
go.mod
View File

@@ -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
)

7
go.sum
View File

@@ -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=

View File

@@ -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()
},
}
@@ -197,3 +198,7 @@ func newChangePVCNodeSelectorItemAction(f client.Factory) veleroplugin.HandlerIn
), nil
}
}
func newAPIServiceRestoreItemAction(logger logrus.FieldLogger) (interface{}, error) {
return restore.NewAPIServiceAction(logger), nil
}

View File

@@ -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
}

View File

@@ -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)
}

View File

@@ -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.
@@ -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(),