mirror of
https://github.com/storytold/irsa-manager.git
synced 2026-10-17 00:23:52 +00:00
secret deletion
This commit is contained in:
@@ -77,7 +77,10 @@ func (r *IRSASetupReconciler) Reconcile(ctx context.Context, req ctrl.Request) (
|
|||||||
}
|
}
|
||||||
|
|
||||||
if !obj.DeletionTimestamp.IsZero() {
|
if !obj.DeletionTimestamp.IsZero() {
|
||||||
err = r.reconcileDelete(ctx, obj)
|
err = r.reconcileDelete(ctx, obj, kubeClient)
|
||||||
|
if err == nil {
|
||||||
|
log.Info("successfully deleted")
|
||||||
|
}
|
||||||
return ctrl.Result{}, err
|
return ctrl.Result{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -94,7 +97,25 @@ func (r *IRSASetupReconciler) reconcile(ctx context.Context, obj *irsav1alpha1.I
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *IRSASetupReconciler) reconcileDelete(ctx context.Context, obj *irsav1alpha1.IRSASetup) error {
|
func (r *IRSASetupReconciler) reconcileDelete(ctx context.Context, obj *irsav1alpha1.IRSASetup, kubeClient *kubernetes.KubernetesClient) error {
|
||||||
|
factory, err := newOIDCIdpFactory(ctx, obj, nil, r.AwsClient)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
secret, err := manifests.NewSecretBuilder().Build("name", "default")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
kubeHandler := handler.NewKubernetesHandler(kubeClient)
|
||||||
|
kubeHandler.Append(secret)
|
||||||
|
err = selfhosted.Delete(ctx, factory)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
err = kubeHandler.DeleteAll(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -38,13 +38,16 @@ var _ = Describe("IRSASetup Controller", func() {
|
|||||||
Context("When reconciling a resource", func() {
|
Context("When reconciling a resource", func() {
|
||||||
const resourceName = "test-resource"
|
const resourceName = "test-resource"
|
||||||
|
|
||||||
ctx := context.Background()
|
|
||||||
|
|
||||||
typeNamespacedName := types.NamespacedName{
|
typeNamespacedName := types.NamespacedName{
|
||||||
Name: resourceName,
|
Name: resourceName,
|
||||||
Namespace: "default", // TODO(user):Modify as needed
|
Namespace: "default",
|
||||||
|
}
|
||||||
|
irsasetup := &irsav1alpha1.IRSASetup{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
|
Name: resourceName,
|
||||||
|
Namespace: "default",
|
||||||
|
},
|
||||||
}
|
}
|
||||||
irsasetup := &irsav1alpha1.IRSASetup{}
|
|
||||||
|
|
||||||
BeforeEach(func() {
|
BeforeEach(func() {
|
||||||
By("creating the custom resource for the Kind IRSASetup")
|
By("creating the custom resource for the Kind IRSASetup")
|
||||||
@@ -69,17 +72,12 @@ var _ = Describe("IRSASetup Controller", func() {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
AfterEach(func() {
|
|
||||||
// TODO(user): Cleanup logic after each test, like removing the resource instance.
|
|
||||||
resource := &irsav1alpha1.IRSASetup{}
|
|
||||||
err := k8sClient.Get(ctx, typeNamespacedName, resource)
|
|
||||||
Expect(err).NotTo(HaveOccurred())
|
|
||||||
|
|
||||||
By("Cleanup the specific resource instance IRSASetup")
|
|
||||||
Expect(k8sClient.Delete(ctx, resource)).To(Succeed())
|
|
||||||
})
|
|
||||||
It("should successfully reconcile the resource", func() {
|
It("should successfully reconcile the resource", func() {
|
||||||
awsClient := newMockAwsClient()
|
awsClient := newMockAwsClient()
|
||||||
|
expected := []types.NamespacedName{
|
||||||
|
{Name: "name", Namespace: "default"},
|
||||||
|
}
|
||||||
|
|
||||||
By("Reconciling the created resource")
|
By("Reconciling the created resource")
|
||||||
controllerReconciler := &IRSASetupReconciler{
|
controllerReconciler := &IRSASetupReconciler{
|
||||||
Client: k8sClient,
|
Client: k8sClient,
|
||||||
@@ -91,8 +89,24 @@ var _ = Describe("IRSASetup Controller", func() {
|
|||||||
NamespacedName: typeNamespacedName,
|
NamespacedName: typeNamespacedName,
|
||||||
})
|
})
|
||||||
Expect(err).NotTo(HaveOccurred())
|
Expect(err).NotTo(HaveOccurred())
|
||||||
// TODO(user): Add more specific assertions depending on your controller's reconciliation logic.
|
_, err = controllerReconciler.Reconcile(ctx, reconcile.Request{
|
||||||
// Example: If you expect a certain status condition after reconciliation, verify it here.
|
NamespacedName: typeNamespacedName,
|
||||||
|
})
|
||||||
|
Expect(err).NotTo(HaveOccurred())
|
||||||
|
for _, expect := range expected {
|
||||||
|
checkExist(expect, newSecret)
|
||||||
|
}
|
||||||
|
By("removing the custom resource for the Kind")
|
||||||
|
Eventually(func() error {
|
||||||
|
return k8sClient.Delete(ctx, irsasetup)
|
||||||
|
}, timeout).Should(Succeed())
|
||||||
|
_, err = controllerReconciler.Reconcile(ctx, reconcile.Request{
|
||||||
|
NamespacedName: typeNamespacedName,
|
||||||
|
})
|
||||||
|
Expect(err).To(Not(HaveOccurred()))
|
||||||
|
for _, expect := range expected {
|
||||||
|
checkNoExist(expect, newSecret)
|
||||||
|
}
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -21,12 +21,16 @@ import (
|
|||||||
"path/filepath"
|
"path/filepath"
|
||||||
"runtime"
|
"runtime"
|
||||||
"testing"
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
. "github.com/onsi/ginkgo/v2"
|
. "github.com/onsi/ginkgo/v2"
|
||||||
. "github.com/onsi/gomega"
|
. "github.com/onsi/gomega"
|
||||||
|
|
||||||
|
corev1 "k8s.io/api/core/v1"
|
||||||
|
"k8s.io/apimachinery/pkg/types"
|
||||||
"k8s.io/client-go/kubernetes/scheme"
|
"k8s.io/client-go/kubernetes/scheme"
|
||||||
"k8s.io/client-go/rest"
|
"k8s.io/client-go/rest"
|
||||||
|
ctrl "sigs.k8s.io/controller-runtime"
|
||||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||||
"sigs.k8s.io/controller-runtime/pkg/envtest"
|
"sigs.k8s.io/controller-runtime/pkg/envtest"
|
||||||
logf "sigs.k8s.io/controller-runtime/pkg/log"
|
logf "sigs.k8s.io/controller-runtime/pkg/log"
|
||||||
@@ -43,6 +47,8 @@ var (
|
|||||||
cfg *rest.Config
|
cfg *rest.Config
|
||||||
k8sClient client.Client
|
k8sClient client.Client
|
||||||
testEnv *envtest.Environment
|
testEnv *envtest.Environment
|
||||||
|
timeout = time.Second * 10
|
||||||
|
ctx = ctrl.SetupSignalHandler()
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestControllers(t *testing.T) {
|
func TestControllers(t *testing.T) {
|
||||||
@@ -89,3 +95,21 @@ var _ = AfterSuite(func() {
|
|||||||
err := testEnv.Stop()
|
err := testEnv.Stop()
|
||||||
Expect(err).NotTo(HaveOccurred())
|
Expect(err).NotTo(HaveOccurred())
|
||||||
})
|
})
|
||||||
|
|
||||||
|
func checkExist(expected types.NamespacedName, newFunc func() client.Object) {
|
||||||
|
Eventually(func() error {
|
||||||
|
found := newFunc()
|
||||||
|
return k8sClient.Get(ctx, expected, found)
|
||||||
|
}, timeout).Should(Succeed())
|
||||||
|
}
|
||||||
|
|
||||||
|
func checkNoExist(expected types.NamespacedName, newFunc func() client.Object) {
|
||||||
|
Eventually(func() error {
|
||||||
|
found := newFunc()
|
||||||
|
return k8sClient.Get(ctx, expected, found)
|
||||||
|
}, timeout).Should(Not(Succeed()))
|
||||||
|
}
|
||||||
|
|
||||||
|
func newSecret() client.Object {
|
||||||
|
return &corev1.Secret{}
|
||||||
|
}
|
||||||
|
|||||||
@@ -4,13 +4,12 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
|
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
|
||||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||||
)
|
)
|
||||||
|
|
||||||
type KubernetesClient interface {
|
type KubernetesClient interface {
|
||||||
Apply(ctx context.Context, obj client.Object) error
|
Apply(ctx context.Context, obj client.Object) error
|
||||||
Delete(ctx context.Context, obj *unstructured.Unstructured, opts DeleteOptions) error
|
Delete(ctx context.Context, obj client.Object, opts DeleteOptions) error
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeleteOptions contains options for delete requests.
|
// DeleteOptions contains options for delete requests.
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package handler
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
|
||||||
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -31,3 +32,15 @@ func (k *KubernetesHandler) ApplyAll(ctx context.Context) error {
|
|||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (k *KubernetesHandler) DeleteAll(ctx context.Context) error {
|
||||||
|
for _, obj := range k.objs {
|
||||||
|
err := k.client.Delete(ctx, obj, DeleteOptions{
|
||||||
|
DeletionPropagation: metav1.DeletePropagationBackground,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|||||||
@@ -3,11 +3,7 @@ package kubernetes
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
|
||||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
|
||||||
"k8s.io/apimachinery/pkg/runtime"
|
|
||||||
|
|
||||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||||
"sigs.k8s.io/controller-runtime/pkg/client/apiutil"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func NewKubernetesClient(c client.Client, owner Owner) (*KubernetesClient, error) {
|
func NewKubernetesClient(c client.Client, owner Owner) (*KubernetesClient, error) {
|
||||||
@@ -22,19 +18,10 @@ func (h KubernetesClient) Apply(ctx context.Context, obj client.Object) error {
|
|||||||
client.ForceOwnership,
|
client.ForceOwnership,
|
||||||
client.FieldOwner(h.owner.Field),
|
client.FieldOwner(h.owner.Field),
|
||||||
}
|
}
|
||||||
gvk, err := apiutil.GVKForObject(obj, h.client.Scheme())
|
u, err := h.toUnstructured(obj)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
u := &unstructured.Unstructured{}
|
|
||||||
unstructured, err := runtime.DefaultUnstructuredConverter.ToUnstructured(obj)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
u.Object = unstructured
|
|
||||||
u.SetGroupVersionKind(gvk)
|
|
||||||
u.SetManagedFields(nil)
|
|
||||||
err = h.client.Patch(ctx, u, client.Apply, opts...)
|
err = h.client.Patch(ctx, u, client.Apply, opts...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@@ -48,18 +35,10 @@ func (h KubernetesClient) PatchStatus(ctx context.Context, obj client.Object) er
|
|||||||
FieldManager: h.owner.Field,
|
FieldManager: h.owner.Field,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
gvk, err := apiutil.GVKForObject(obj, h.client.Scheme())
|
u, err := h.toUnstructured(obj)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
u := &unstructured.Unstructured{}
|
|
||||||
unstructured, err := runtime.DefaultUnstructuredConverter.ToUnstructured(obj)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
u.Object = unstructured
|
|
||||||
u.SetGroupVersionKind(gvk)
|
|
||||||
u.SetManagedFields(nil)
|
|
||||||
return h.client.Status().Patch(ctx, u, client.Apply, opts)
|
return h.client.Status().Patch(ctx, u, client.Apply, opts)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,27 +14,15 @@ import (
|
|||||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (h *KubernetesClient) DeleteAll(ctx context.Context, resources []*unstructured.Unstructured, opts handler.DeleteOptions) error {
|
|
||||||
if !h.cleanup {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
for _, r := range resources {
|
|
||||||
err := h.Delete(ctx, r, opts)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Delete deletes the given object (not found errors are ignored).
|
// Delete deletes the given object (not found errors are ignored).
|
||||||
func (h *KubernetesClient) Delete(ctx context.Context, object *unstructured.Unstructured, opts handler.DeleteOptions) error {
|
func (h *KubernetesClient) Delete(ctx context.Context, obj client.Object, opts handler.DeleteOptions) error {
|
||||||
if !h.cleanup {
|
u, err := h.toUnstructured(obj)
|
||||||
return nil
|
if err != nil {
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
existingObject := &unstructured.Unstructured{}
|
existingObject := &unstructured.Unstructured{}
|
||||||
existingObject.SetGroupVersionKind(object.GroupVersionKind())
|
existingObject.SetGroupVersionKind(u.GroupVersionKind())
|
||||||
err := h.client.Get(ctx, client.ObjectKeyFromObject(object), existingObject)
|
err = h.client.Get(ctx, client.ObjectKeyFromObject(u), existingObject)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if !errors.IsNotFound(err) {
|
if !errors.IsNotFound(err) {
|
||||||
return fmt.Errorf("failed to delete: %w", err)
|
return fmt.Errorf("failed to delete: %w", err)
|
||||||
|
|||||||
@@ -0,0 +1,26 @@
|
|||||||
|
package kubernetes
|
||||||
|
|
||||||
|
import (
|
||||||
|
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||||
|
"k8s.io/apimachinery/pkg/runtime"
|
||||||
|
|
||||||
|
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||||
|
"sigs.k8s.io/controller-runtime/pkg/client/apiutil"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (h KubernetesClient) toUnstructured(obj client.Object) (*unstructured.Unstructured, error) {
|
||||||
|
gvk, err := apiutil.GVKForObject(obj, h.client.Scheme())
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
u := &unstructured.Unstructured{}
|
||||||
|
unstructured, err := runtime.DefaultUnstructuredConverter.ToUnstructured(obj)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
u.Object = unstructured
|
||||||
|
u.SetGroupVersionKind(gvk)
|
||||||
|
u.SetManagedFields(nil)
|
||||||
|
return u, nil
|
||||||
|
}
|
||||||
@@ -1,8 +1,6 @@
|
|||||||
package manifests
|
package manifests
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
|
|
||||||
"github.com/kkb0318/irsa-manager/internal/selfhosted"
|
"github.com/kkb0318/irsa-manager/internal/selfhosted"
|
||||||
corev1 "k8s.io/api/core/v1"
|
corev1 "k8s.io/api/core/v1"
|
||||||
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
@@ -29,9 +27,6 @@ func (b *SecretBuilder) WithSSHKey(keyPair selfhosted.KeyPair) *SecretBuilder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (b *SecretBuilder) Build(name, ns string) (*corev1.Secret, error) {
|
func (b *SecretBuilder) Build(name, ns string) (*corev1.Secret, error) {
|
||||||
if b.data == nil {
|
|
||||||
return nil, fmt.Errorf("Secret.Data is empty")
|
|
||||||
}
|
|
||||||
secret := &corev1.Secret{
|
secret := &corev1.Secret{
|
||||||
ObjectMeta: v1.ObjectMeta{
|
ObjectMeta: v1.ObjectMeta{
|
||||||
Name: name,
|
Name: name,
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ type OIDCIdP interface {
|
|||||||
Create(ctx context.Context) (string, error)
|
Create(ctx context.Context) (string, error)
|
||||||
IsUpdate() (bool, error)
|
IsUpdate() (bool, error)
|
||||||
Update(ctx context.Context) error
|
Update(ctx context.Context) error
|
||||||
|
Delete(ctx context.Context) error
|
||||||
}
|
}
|
||||||
|
|
||||||
type OIDCIdPDiscoveryContents interface {
|
type OIDCIdPDiscoveryContents interface {
|
||||||
@@ -22,6 +23,7 @@ type OIDCIdPDiscoveryContents interface {
|
|||||||
type OIDCIdPDiscovery interface {
|
type OIDCIdPDiscovery interface {
|
||||||
CreateStorage(ctx context.Context) error
|
CreateStorage(ctx context.Context) error
|
||||||
Upload(ctx context.Context, o OIDCIdPDiscoveryContents) error
|
Upload(ctx context.Context, o OIDCIdPDiscoveryContents) error
|
||||||
|
DeleteStorage(ctx context.Context) error
|
||||||
}
|
}
|
||||||
|
|
||||||
type OIDCIdPFactory interface {
|
type OIDCIdPFactory interface {
|
||||||
|
|||||||
@@ -32,3 +32,8 @@ func (a *AwsIdP) Update(ctx context.Context) error {
|
|||||||
func (a *AwsIdP) IsUpdate() (bool, error) {
|
func (a *AwsIdP) IsUpdate() (bool, error) {
|
||||||
return false, nil
|
return false, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (a *AwsIdP) Delete(ctx context.Context) error {
|
||||||
|
// TODO:
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|||||||
@@ -59,3 +59,9 @@ func (s *S3IdPDiscovery) Upload(ctx context.Context, o selfhosted.OIDCIdPDiscove
|
|||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DeleteStorage delete an S3 bucket
|
||||||
|
func (s *S3IdPDiscovery) DeleteStorage(ctx context.Context) error {
|
||||||
|
// TODO:
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|||||||
@@ -24,3 +24,21 @@ func Execute(ctx context.Context, factory OIDCIdPFactory) error {
|
|||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func Delete(ctx context.Context, factory OIDCIdPFactory) error {
|
||||||
|
issuerMeta := factory.IssuerMeta()
|
||||||
|
discovery := factory.IdPDiscovery()
|
||||||
|
idp, err := factory.IdP(issuerMeta)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
err = discovery.DeleteStorage(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
err = idp.Delete(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user