Skip to content

Commit

Permalink
[GEP-13] Add ManagedSeed admission plugins (gardener#3416)
Browse files Browse the repository at this point in the history
  • Loading branch information
stoyanr authored and Kristiyan Gostev committed Apr 21, 2022
1 parent 8b55192 commit dc56749
Show file tree
Hide file tree
Showing 10 changed files with 1,579 additions and 0 deletions.
8 changes: 8 additions & 0 deletions pkg/apiserver/plugins.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,11 @@ import (
"github.com/gardener/gardener/plugin/pkg/global/deletionconfirmation"
"github.com/gardener/gardener/plugin/pkg/global/extensionvalidation"
"github.com/gardener/gardener/plugin/pkg/global/resourcereferencemanager"
managedseedvalidator "github.com/gardener/gardener/plugin/pkg/managedseed/validator"
plantvalidator "github.com/gardener/gardener/plugin/pkg/plant"
seedvalidator "github.com/gardener/gardener/plugin/pkg/seed/validator"
shootdns "github.com/gardener/gardener/plugin/pkg/shoot/dns"
shootmanagedseed "github.com/gardener/gardener/plugin/pkg/shoot/managedseed"
"github.com/gardener/gardener/plugin/pkg/shoot/oidc/clusteropenidconnectpreset"
"github.com/gardener/gardener/plugin/pkg/shoot/oidc/openidconnectpreset"
shootquotavalidator "github.com/gardener/gardener/plugin/pkg/shoot/quotavalidator"
Expand All @@ -47,6 +49,7 @@ var (
extensionvalidation.PluginName, // ExtensionValidator
shoottolerationrestriction.PluginName, // ShootTolerationRestriction
shootdns.PluginName, // ShootDNS
shootmanagedseed.PluginName, // ShootManagedSeed
shootquotavalidator.PluginName, // ShootQuotaValidator
shootvalidator.PluginName, // ShootValidator
seedvalidator.PluginName, // SeedValidator
Expand All @@ -58,6 +61,7 @@ var (
shootstatedeletionvalidator.PluginName, // ShootStateDeletionValidator
customverbauthorizer.PluginName, // CustomVerbAuthorizer
shootvpa.PluginName, // ShootVPAEnabledByDefault
managedseedvalidator.PluginName, // ManagedSeed

// new admission plugins should generally be inserted above here
// webhook, and resourcequota plugins must go at the end
Expand All @@ -77,6 +81,7 @@ var (
extensionvalidation.PluginName, // ExtensionValidator
shoottolerationrestriction.PluginName, // ShootTolerationRestriction
shootdns.PluginName, // ShootDNS
shootmanagedseed.PluginName, // ShootManagedSeed
shootquotavalidator.PluginName, // ShootQuotaValidator
shootvalidator.PluginName, // ShootValidator
seedvalidator.PluginName, // SeedValidator
Expand All @@ -87,6 +92,7 @@ var (
clusteropenidconnectpreset.PluginName, // ClusterOpenIDConnectPreset
shootstatedeletionvalidator.PluginName, // ShootStateDeletionValidator
customverbauthorizer.PluginName, // CustomVerbAuthorizer
managedseedvalidator.PluginName, // ManagedSeed
mutatingwebhook.PluginName, // MutatingAdmissionWebhook
validatingwebhook.PluginName, // ValidatingAdmissionWebhook
resourcequota.PluginName, // ResourceQuota
Expand All @@ -104,6 +110,7 @@ func RegisterAllAdmissionPlugins(plugins *admission.Plugins) {
shoottolerationrestriction.Register(plugins)
shootquotavalidator.Register(plugins)
shootdns.Register(plugins)
shootmanagedseed.Register(plugins)
shootvalidator.Register(plugins)
seedvalidator.Register(plugins)
controllerregistrationresources.Register(plugins)
Expand All @@ -112,6 +119,7 @@ func RegisterAllAdmissionPlugins(plugins *admission.Plugins) {
clusteropenidconnectpreset.Register(plugins)
shootstatedeletionvalidator.Register(plugins)
customverbauthorizer.Register(plugins)
managedseedvalidator.Register(plugins)
resourcequota.Register(plugins)
shootvpa.Register(plugins)
}
46 changes: 46 additions & 0 deletions pkg/utils/kubernetes/managedseed.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
// Copyright (c) 2021 SAP SE or an SAP affiliate company. All rights reserved. This file is licensed under the Apache Software License, v. 2 except as noted otherwise in the LICENSE file
//
// 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 kubernetes

import (
"context"
"fmt"

"github.com/gardener/gardener/pkg/apis/seedmanagement"
seedmanagementv1alpha1 "github.com/gardener/gardener/pkg/apis/seedmanagement/v1alpha1"
gardenseedmanagementclientset "github.com/gardener/gardener/pkg/client/seedmanagement/clientset/versioned"

metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/fields"
)

// GetManagedSeed gets the ManagedSeed resource for the given shoot namespace and name,
// by searching for all ManagedSeeds in the shoot namespace that have spec.shoot.name set to the shoot name.
// If no such ManagedSeeds are found, nil is returned.
func GetManagedSeed(ctx context.Context, seedManagementClient gardenseedmanagementclientset.Interface, shootNamespace, shootName string) (*seedmanagementv1alpha1.ManagedSeed, error) {
managedSeedList, err := seedManagementClient.SeedmanagementV1alpha1().ManagedSeeds(shootNamespace).List(ctx, metav1.ListOptions{
FieldSelector: fields.SelectorFromSet(fields.Set{seedmanagement.ManagedSeedShootName: shootName}).String(),
})
if err != nil {
return nil, err
}
if len(managedSeedList.Items) == 0 {
return nil, nil
}
if len(managedSeedList.Items) > 1 {
return nil, fmt.Errorf("found more than one ManagedSeed objects for shoot %s/%s", shootNamespace, shootName)
}
return &managedSeedList.Items[0], nil
}
98 changes: 98 additions & 0 deletions pkg/utils/kubernetes/managedseed_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
// Copyright (c) 2021 SAP SE or an SAP affiliate company. All rights reserved. This file is licensed under the Apache Software License, v. 2 except as noted otherwise in the LICENSE file
//
// 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 kubernetes_test

import (
"context"
"errors"

seedmanagementv1alpha1 "github.com/gardener/gardener/pkg/apis/seedmanagement/v1alpha1"
seedmanagementfake "github.com/gardener/gardener/pkg/client/seedmanagement/clientset/versioned/fake"
. "github.com/gardener/gardener/pkg/utils/kubernetes"

. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/client-go/testing"
)

const (
name = "foo"
namespace = "garden"
)

var _ = Describe("managedseed", func() {
Describe("#GetManagedSeed", func() {
var (
seedManagementClient *seedmanagementfake.Clientset
managedSeed *seedmanagementv1alpha1.ManagedSeed
)

BeforeEach(func() {
seedManagementClient = &seedmanagementfake.Clientset{}

managedSeed = &seedmanagementv1alpha1.ManagedSeed{
ObjectMeta: metav1.ObjectMeta{
Name: name,
Namespace: namespace,
},
Spec: seedmanagementv1alpha1.ManagedSeedSpec{
Shoot: seedmanagementv1alpha1.Shoot{
Name: name,
},
},
}
})

It("should return the ManagedSeed for the given shoot namespace and name, if it exists", func() {
seedManagementClient.AddReactor("list", "managedseeds", func(action testing.Action) (bool, runtime.Object, error) {
return true, &seedmanagementv1alpha1.ManagedSeedList{Items: []seedmanagementv1alpha1.ManagedSeed{*managedSeed}}, nil
})

result, err := GetManagedSeed(context.TODO(), seedManagementClient, namespace, name)
Expect(err).NotTo(HaveOccurred())
Expect(result).To(Equal(managedSeed))
})

It("should return nil if a ManagedSeed does not exist", func() {
seedManagementClient.AddReactor("list", "managedseeds", func(action testing.Action) (bool, runtime.Object, error) {
return true, &seedmanagementv1alpha1.ManagedSeedList{Items: []seedmanagementv1alpha1.ManagedSeed{}}, nil
})

result, err := GetManagedSeed(context.TODO(), seedManagementClient, namespace, name)
Expect(err).NotTo(HaveOccurred())
Expect(result).To(BeNil())
})

It("should fail if more than one ManagedSeeds exist", func() {
seedManagementClient.AddReactor("list", "managedseeds", func(action testing.Action) (bool, runtime.Object, error) {
return true, &seedmanagementv1alpha1.ManagedSeedList{Items: []seedmanagementv1alpha1.ManagedSeed{*managedSeed, *managedSeed}}, nil
})

_, err := GetManagedSeed(context.TODO(), seedManagementClient, namespace, name)
Expect(err).To(HaveOccurred())
})

It("should fail if listing the ManagedSeeds fails", func() {
seedManagementClient.AddReactor("list", "managedseeds", func(action testing.Action) (bool, runtime.Object, error) {
return true, nil, errors.New("error")
})

_, err := GetManagedSeed(context.TODO(), seedManagementClient, namespace, name)
Expect(err).To(HaveOccurred())
})
})
})
8 changes: 8 additions & 0 deletions pkg/utils/test/matchers/matchers.go
Original file line number Diff line number Diff line change
Expand Up @@ -102,3 +102,11 @@ func BeInternalServerError() types.GomegaMatcher {
message: "",
}
}

// BeInvalidError checks if error is an InvalidError.
func BeInvalidError() types.GomegaMatcher {
return &kubernetesErrors{
checkFunc: apierrors.IsInvalid,
message: "Invalid",
}
}
Loading

0 comments on commit dc56749

Please sign in to comment.