Skip to content

Commit

Permalink
feat(pluginpresets) Deny plugin creation only deploy metohd is via Pl…
Browse files Browse the repository at this point in the history
…uginPreset (#829)
  • Loading branch information
gciezkowski-acc committed Jan 9, 2025
1 parent cf11276 commit 5d8561c
Show file tree
Hide file tree
Showing 6 changed files with 79 additions and 7 deletions.
25 changes: 18 additions & 7 deletions e2e/plugin/e2e_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ var _ = Describe("Plugin E2E", Ordered, func() {
Eventually(func(g Gomega) {
err := adminClient.Get(ctx, client.ObjectKey{Name: remoteClusterName, Namespace: env.TestNamespace}, &greenhousev1alpha1.Cluster{})
g.Expect(err).ToNot(HaveOccurred())

}).Should(Succeed(), "cluster resource should be created")

By("verifying the cluster status is ready")
Expand All @@ -90,16 +91,26 @@ var _ = Describe("Plugin E2E", Ordered, func() {
Expect(err).NotTo(HaveOccurred())
Expect(len(pluginDefinitionList.Items)).To(BeEquivalentTo(1))

By("Creating the plugin")
By("Try to creating the plugin")
// Creating plugin
testPlugin := fixtures.PreparePlugin("test-nginx-plugin", env.TestNamespace,
test.WithPluginDefinition(testPluginDefinition.Name),
test.WithCluster(remoteClusterName),
test.WithReleaseNamespace(env.TestNamespace),
test.WithPluginOptionValue("replicaCount", &apiextensionsv1.JSON{Raw: []byte("1")}, nil))
err = adminClient.Create(ctx, testPlugin)
Expect(err).To(HaveOccurred())

By("Creating the plugin preset")
testPluginPreset := fixtures.PreparePluginPreset("test-nginx-preset", env.TestNamespace, testPlugin.Spec)
err = adminClient.Create(ctx, testPluginPreset)
Expect(err).ToNot(HaveOccurred())

By("Checking the plugin preset is ready")
Eventually(func(g Gomega) {
err = adminClient.Get(ctx, client.ObjectKeyFromObject(testPluginPreset), testPluginPreset)
g.Expect(err).ToNot(HaveOccurred())
}).Should(Succeed())

By("Checking the plugin status is ready")
pluginList := &greenhousev1alpha1.PluginList{}
Eventually(func(g Gomega) {
Expand Down Expand Up @@ -131,11 +142,11 @@ var _ = Describe("Plugin E2E", Ordered, func() {

By("Updating replicas")
Eventually(func(g Gomega) {
namespacedName := types.NamespacedName{Name: testPlugin.Name, Namespace: env.TestNamespace}
err = adminClient.Get(ctx, namespacedName, testPlugin)
namespacedName := types.NamespacedName{Name: testPluginPreset.Name, Namespace: testPluginPreset.Namespace}
err = adminClient.Get(ctx, namespacedName, testPluginPreset)
g.Expect(err).NotTo(HaveOccurred())
test.SetOptionValueForPlugin(testPlugin, "replicaCount", "2")
err = adminClient.Update(ctx, testPlugin)
test.SetOptionValueForPluginPreset(testPluginPreset, "replicaCount", "2")
err = adminClient.Update(ctx, testPluginPreset)
g.Expect(err).NotTo(HaveOccurred())
}).Should(Succeed())

Expand All @@ -151,7 +162,7 @@ var _ = Describe("Plugin E2E", Ordered, func() {
}).Should(Succeed())

By("Deleting plugin")
test.EventuallyDeleted(ctx, adminClient, testPlugin)
test.EventuallyDeleted(ctx, adminClient, testPluginPreset)

By("Check, is deployment deleted")
Eventually(func(g Gomega) bool {
Expand Down
24 changes: 24 additions & 0 deletions e2e/plugin/fixtures/fixtures.go
Original file line number Diff line number Diff line change
Expand Up @@ -101,3 +101,27 @@ func PreparePlugin(name, namespace string, opts ...func(*greenhousev1alpha1.Plug
}
return plugin
}

func PreparePluginPreset(name, namespace string, pluginSpec greenhousev1alpha1.PluginSpec) *greenhousev1alpha1.PluginPreset {
pluginPreset := &greenhousev1alpha1.PluginPreset{
TypeMeta: metav1.TypeMeta{
Kind: "PluginPreset",
APIVersion: greenhousev1alpha1.GroupVersion.String(),
},
ObjectMeta: metav1.ObjectMeta{
Name: name,
Namespace: namespace,
GenerateName: name + "-gen",
},
Spec: greenhousev1alpha1.PluginPresetSpec{
Plugin: pluginSpec,
ClusterSelector: metav1.LabelSelector{
MatchLabels: map[string]string{
"app": "test",
},
},
},
}

return pluginPreset
}
3 changes: 3 additions & 0 deletions e2e/shared/cluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@ func OnboardRemoteCluster(ctx context.Context, k8sClient client.Client, kubeConf
ObjectMeta: metav1.ObjectMeta{
Name: name,
Namespace: namespace,
Labels: map[string]string{
"app": "test",
},
},
Type: greenhouseapis.SecretTypeKubeConfig,
Data: map[string][]byte{
Expand Down
11 changes: 11 additions & 0 deletions pkg/admission/plugin_webhook.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ package admission
import (
"context"
"encoding/json"
"errors"
"fmt"
"strings"

Expand Down Expand Up @@ -88,6 +89,10 @@ func ValidateCreatePlugin(ctx context.Context, c client.Client, obj runtime.Obje
return nil, nil
}

if !allowCreatePlugin(plugin) {
return nil, errors.New("plugin creation is not allowed")
}

pluginDefinition := new(greenhousev1alpha1.PluginDefinition)
err := c.Get(ctx, client.ObjectKey{Namespace: "", Name: plugin.Spec.PluginDefinition}, pluginDefinition)
if err != nil {
Expand Down Expand Up @@ -144,6 +149,12 @@ func ValidateDeletePlugin(_ context.Context, _ client.Client, _ runtime.Object)
return nil, nil
}

func allowCreatePlugin(plugin *greenhousev1alpha1.Plugin) bool {
_, ok := plugin.Annotations["greenhouse.sap/allow-create"]
delete(plugin.Annotations, "greenhouse.sap/allow-create")
return ok
}

// validateOwnerRefernce returns a Warning if the Plugin is managed by a PluginPreset
// The user is warned that the Plugin will be reconciled to the desired state specified in the PluginPreset.
func validateOwnerReference(plugin *greenhousev1alpha1.Plugin) admission.Warnings {
Expand Down
8 changes: 8 additions & 0 deletions pkg/controllers/plugin/pluginpreset_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,15 @@ func (r *PluginPresetReconciler) reconcilePluginPreset(ctx context.Context, pres
return err
}

log.FromContext(ctx).Info("======================== OOOOOOOOOO", "cluster", cluster)
_, err = clientutil.CreateOrPatch(ctx, r.Client, plugin, func() error {
// Add annotation to allow plugin creation
if plugin.Annotations == nil {
plugin.Annotations = make(map[string]string)
}

plugin.Annotations["greenhouse.sap/allow-create"] = "true"

// Label the plugin with the managed resource label to identify it as managed by the PluginPreset.
plugin.SetLabels(map[string]string{greenhouseapis.LabelKeyPluginPreset: preset.Name})
// Set the owner reference to the PluginPreset. This is used to trigger reconciliation, if the managed Plugin is modified.
Expand Down
15 changes: 15 additions & 0 deletions pkg/test/resources.go
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,21 @@ func SetOptionValueForPlugin(plugin *greenhousev1alpha1.Plugin, key, value strin
})
}

// SetOptionValueForPluginPreset sets the value of a PluginOtionValue
func SetOptionValueForPluginPreset(pluginPreset *greenhousev1alpha1.PluginPreset, key, value string) {
for i, keyValue := range pluginPreset.Spec.Plugin.OptionValues {
if keyValue.Name == key {
pluginPreset.Spec.Plugin.OptionValues[i].Value.Raw = []byte(value)
return
}
}

pluginPreset.Spec.Plugin.OptionValues = append(pluginPreset.Spec.Plugin.OptionValues, greenhousev1alpha1.PluginOptionValue{
Name: key,
Value: &apiextensionsv1.JSON{Raw: []byte(value)},
})
}

// NewPlugin returns a greenhousev1alpha1.Plugin object. Opts can be used to set the desired state of the Plugin.
func NewPlugin(ctx context.Context, name, namespace string, opts ...func(*greenhousev1alpha1.Plugin)) *greenhousev1alpha1.Plugin {
GinkgoHelper()
Expand Down

0 comments on commit 5d8561c

Please sign in to comment.