From 9eae402c5bd2f8035beebff1b3f73cd3409288bc Mon Sep 17 00:00:00 2001 From: Ori Shoshan Date: Sat, 18 Nov 2023 16:32:44 +0100 Subject: [PATCH 1/6] Add pod webhook that makes sure service accounts are annotated prior to pod being created --- src/operator/Makefile | 5 +- src/operator/PROJECT | 7 +- src/operator/README.md | 2 +- .../config/certmanager/certificate.yaml | 25 ---- .../config/certmanager/kustomization.yaml | 5 - .../config/certmanager/kustomizeconfig.yaml | 16 --- src/operator/config/rbac/role.yaml | 2 +- .../config/samples/kustomization.yaml | 4 - .../config/scorecard/bases/config.yaml | 7 - .../config/scorecard/kustomization.yaml | 16 --- .../scorecard/patches/basic.config.yaml | 10 -- .../config/scorecard/patches/olm.config.yaml | 50 ------- .../config/webhook/kustomization.yaml | 22 +++ .../config/webhook/kustomizeconfig.yaml | 12 ++ src/operator/config/webhook/manifests.yaml | 27 ++++ .../controllers/metadata/annotations.go | 4 + src/operator/controllers/metadata/labels.go | 2 +- .../service_account_pod_reconciler.go | 96 ------------- .../service_account_pod_reconciler_test.go | 127 ------------------ .../serviceaccount_controller.go | 60 +++++---- .../controllers/webhooks/pod_webhook.go | 124 +++++++++++++++++ src/operator/go.mod | 35 ++--- src/operator/go.sum | 75 ++++++----- src/operator/main.go | 42 +++++- 24 files changed, 323 insertions(+), 452 deletions(-) delete mode 100644 src/operator/config/certmanager/certificate.yaml delete mode 100644 src/operator/config/certmanager/kustomization.yaml delete mode 100644 src/operator/config/certmanager/kustomizeconfig.yaml delete mode 100644 src/operator/config/samples/kustomization.yaml delete mode 100644 src/operator/config/scorecard/bases/config.yaml delete mode 100644 src/operator/config/scorecard/kustomization.yaml delete mode 100644 src/operator/config/scorecard/patches/basic.config.yaml delete mode 100644 src/operator/config/scorecard/patches/olm.config.yaml create mode 100644 src/operator/config/webhook/kustomization.yaml create mode 100644 src/operator/config/webhook/kustomizeconfig.yaml create mode 100644 src/operator/config/webhook/manifests.yaml delete mode 100644 src/operator/controllers/service_account_pod/service_account_pod_reconciler.go delete mode 100644 src/operator/controllers/service_account_pod/service_account_pod_reconciler_test.go create mode 100644 src/operator/controllers/webhooks/pod_webhook.go diff --git a/src/operator/Makefile b/src/operator/Makefile index 91f879e..8e0ee8f 100644 --- a/src/operator/Makefile +++ b/src/operator/Makefile @@ -88,11 +88,12 @@ help: ## Display this help. .PHONY: manifests manifests: controller-gen ## Generate WebhookConfiguration, ClusterRole and CustomResourceDefinition objects. - $(CONTROLLER_GEN) rbac:roleName=manager-role crd webhook paths="./..." output:crd:artifacts:config=config/crd/bases + $(CONTROLLER_GEN) rbac:roleName=credentials-operator-manager-role crd webhook paths="./..." + kubectl kustomize ./config/webhook > ./config/webhook/manifests-patched .PHONY: generate generate: controller-gen ## Generate code containing DeepCopy, DeepCopyInto, and DeepCopyObject method implementations. - $(CONTROLLER_GEN) object:headerFile="hack/boilerplate.go.txt" paths="./..." + $(CONTROLLER_GEN) object:headerFile="hack/boilerplate.go.txt" paths="../..." .PHONY: fmt fmt: ## Run go fmt against code. diff --git a/src/operator/PROJECT b/src/operator/PROJECT index 786d3cc..494041b 100644 --- a/src/operator/PROJECT +++ b/src/operator/PROJECT @@ -3,13 +3,14 @@ layout: - go.kubebuilder.io/v3 plugins: manifests.sdk.operatorframework.io/v2: {} - scorecard.sdk.operatorframework.io/v2: {} -projectName: spire-integration-operator -repo: github.com/otterize/spire-integration-operator +projectName: credentials-operator +repo: github.com/otterize/credentials-operator resources: - controller: true group: core kind: Pod path: k8s.io/api/core/v1 version: v1 + webhooks: + webhookVersion: v1 version: "3" diff --git a/src/operator/README.md b/src/operator/README.md index 155480f..138b33a 100644 --- a/src/operator/README.md +++ b/src/operator/README.md @@ -41,7 +41,7 @@ This project aims to follow the Kubernetes [Operator pattern](https://kubernetes It uses [Controllers](https://kubernetes.io/docs/concepts/architecture/controller/) which provides a reconcile function responsible for synchronizing resources untile the desired state is reached on the cluster -### Test It Out +### Test it out 1. Install a SPIRE server. You can use the [SPIRE server from the helm-charts repository](https://github.com/otterize/helm-charts/tree/main/spire). 2. If you are running this locally against a SPIRE server, and did not install it using the [Otterize all-in-one helm chart](https://github.com/otterize/helm-charts/tree/main/otterize-kubernetes), then you need to create a SPIRE server entry for the operator: diff --git a/src/operator/config/certmanager/certificate.yaml b/src/operator/config/certmanager/certificate.yaml deleted file mode 100644 index 52d8661..0000000 --- a/src/operator/config/certmanager/certificate.yaml +++ /dev/null @@ -1,25 +0,0 @@ -# The following manifests contain a self-signed issuer CR and a certificate CR. -# More document can be found at https://docs.cert-manager.io -# WARNING: Targets CertManager v1.0. Check https://cert-manager.io/docs/installation/upgrading/ for breaking changes. -apiVersion: cert-manager.io/v1 -kind: Issuer -metadata: - name: selfsigned-issuer - namespace: system -spec: - selfSigned: {} ---- -apiVersion: cert-manager.io/v1 -kind: Certificate -metadata: - name: serving-cert # this name should match the one appeared in kustomizeconfig.yaml - namespace: system -spec: - # $(SERVICE_NAME) and $(SERVICE_NAMESPACE) will be substituted by kustomize - dnsNames: - - $(SERVICE_NAME).$(SERVICE_NAMESPACE).svc - - $(SERVICE_NAME).$(SERVICE_NAMESPACE).svc.cluster.local - issuerRef: - kind: Issuer - name: selfsigned-issuer - secretName: webhook-server-cert # this secret will not be prefixed, since it's not managed by kustomize diff --git a/src/operator/config/certmanager/kustomization.yaml b/src/operator/config/certmanager/kustomization.yaml deleted file mode 100644 index bebea5a..0000000 --- a/src/operator/config/certmanager/kustomization.yaml +++ /dev/null @@ -1,5 +0,0 @@ -resources: -- certificate.yaml - -configurations: -- kustomizeconfig.yaml diff --git a/src/operator/config/certmanager/kustomizeconfig.yaml b/src/operator/config/certmanager/kustomizeconfig.yaml deleted file mode 100644 index 90d7c31..0000000 --- a/src/operator/config/certmanager/kustomizeconfig.yaml +++ /dev/null @@ -1,16 +0,0 @@ -# This configuration is for teaching kustomize how to update name ref and var substitution -nameReference: -- kind: Issuer - group: cert-manager.io - fieldSpecs: - - kind: Certificate - group: cert-manager.io - path: spec/issuerRef/name - -varReference: -- kind: Certificate - group: cert-manager.io - path: spec/commonName -- kind: Certificate - group: cert-manager.io - path: spec/dnsNames diff --git a/src/operator/config/rbac/role.yaml b/src/operator/config/rbac/role.yaml index 2fe3dd1..b3f630e 100644 --- a/src/operator/config/rbac/role.yaml +++ b/src/operator/config/rbac/role.yaml @@ -3,7 +3,7 @@ apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: creationTimestamp: null - name: manager-role + name: credentials-operator-manager-role rules: - apiGroups: - "" diff --git a/src/operator/config/samples/kustomization.yaml b/src/operator/config/samples/kustomization.yaml deleted file mode 100644 index f1accc6..0000000 --- a/src/operator/config/samples/kustomization.yaml +++ /dev/null @@ -1,4 +0,0 @@ -## Append samples you want in your CSV to this file as resources ## -resources: -- core_v1_pod.yaml -#+kubebuilder:scaffold:manifestskustomizesamples diff --git a/src/operator/config/scorecard/bases/config.yaml b/src/operator/config/scorecard/bases/config.yaml deleted file mode 100644 index c770478..0000000 --- a/src/operator/config/scorecard/bases/config.yaml +++ /dev/null @@ -1,7 +0,0 @@ -apiVersion: scorecard.operatorframework.io/v1alpha3 -kind: Configuration -metadata: - name: config -stages: -- parallel: true - tests: [] diff --git a/src/operator/config/scorecard/kustomization.yaml b/src/operator/config/scorecard/kustomization.yaml deleted file mode 100644 index 50cd2d0..0000000 --- a/src/operator/config/scorecard/kustomization.yaml +++ /dev/null @@ -1,16 +0,0 @@ -resources: -- bases/config.yaml -patchesJson6902: -- path: patches/basic.config.yaml - target: - group: scorecard.operatorframework.io - version: v1alpha3 - kind: Configuration - name: config -- path: patches/olm.config.yaml - target: - group: scorecard.operatorframework.io - version: v1alpha3 - kind: Configuration - name: config -#+kubebuilder:scaffold:patchesJson6902 diff --git a/src/operator/config/scorecard/patches/basic.config.yaml b/src/operator/config/scorecard/patches/basic.config.yaml deleted file mode 100644 index 721b95f..0000000 --- a/src/operator/config/scorecard/patches/basic.config.yaml +++ /dev/null @@ -1,10 +0,0 @@ -- op: add - path: /stages/0/tests/- - value: - entrypoint: - - scorecard-test - - basic-check-spec - image: quay.io/operator-framework/scorecard-test:v1.22.0 - labels: - suite: basic - test: basic-check-spec-test diff --git a/src/operator/config/scorecard/patches/olm.config.yaml b/src/operator/config/scorecard/patches/olm.config.yaml deleted file mode 100644 index be12e2c..0000000 --- a/src/operator/config/scorecard/patches/olm.config.yaml +++ /dev/null @@ -1,50 +0,0 @@ -- op: add - path: /stages/0/tests/- - value: - entrypoint: - - scorecard-test - - olm-bundle-validation - image: quay.io/operator-framework/scorecard-test:v1.22.0 - labels: - suite: olm - test: olm-bundle-validation-test -- op: add - path: /stages/0/tests/- - value: - entrypoint: - - scorecard-test - - olm-crds-have-validation - image: quay.io/operator-framework/scorecard-test:v1.22.0 - labels: - suite: olm - test: olm-crds-have-validation-test -- op: add - path: /stages/0/tests/- - value: - entrypoint: - - scorecard-test - - olm-crds-have-resources - image: quay.io/operator-framework/scorecard-test:v1.22.0 - labels: - suite: olm - test: olm-crds-have-resources-test -- op: add - path: /stages/0/tests/- - value: - entrypoint: - - scorecard-test - - olm-spec-descriptors - image: quay.io/operator-framework/scorecard-test:v1.22.0 - labels: - suite: olm - test: olm-spec-descriptors-test -- op: add - path: /stages/0/tests/- - value: - entrypoint: - - scorecard-test - - olm-status-descriptors - image: quay.io/operator-framework/scorecard-test:v1.22.0 - labels: - suite: olm - test: olm-status-descriptors-test diff --git a/src/operator/config/webhook/kustomization.yaml b/src/operator/config/webhook/kustomization.yaml new file mode 100644 index 0000000..54640e1 --- /dev/null +++ b/src/operator/config/webhook/kustomization.yaml @@ -0,0 +1,22 @@ +resources: +- manifests.yaml + +configurations: +- kustomizeconfig.yaml + +patches: + - patch: |- + - op: replace + path: /metadata/name + value: 'otterize-credentials-operator-validating-webhook-configuration' + - op: replace + path: /webhooks/0/clientConfig/service/namespace + value: '{{ .Release.Namespace }}' + - op: replace + path: /webhooks/0/clientConfig/service/name + value: credentials-operator-webhook-service + - op: replace + path: /webhooks/0/clientConfig/service/namespace + value: '{{ .Release.Namespace }}' + target: + kind: MutatingWebhookConfiguration \ No newline at end of file diff --git a/src/operator/config/webhook/kustomizeconfig.yaml b/src/operator/config/webhook/kustomizeconfig.yaml new file mode 100644 index 0000000..3d641e0 --- /dev/null +++ b/src/operator/config/webhook/kustomizeconfig.yaml @@ -0,0 +1,12 @@ +# the following config is for teaching kustomize where to look at when substituting vars. +# It requires kustomize v2.1.0 or newer to work properly. +nameReference: + +namespace: +- kind: MutatingWebhookConfiguration + group: admissionregistration.k8s.io + path: webhooks/clientConfig/service/namespace + create: true + +varReference: +- path: metadata/annotations diff --git a/src/operator/config/webhook/manifests.yaml b/src/operator/config/webhook/manifests.yaml new file mode 100644 index 0000000..288f240 --- /dev/null +++ b/src/operator/config/webhook/manifests.yaml @@ -0,0 +1,27 @@ +--- +apiVersion: admissionregistration.k8s.io/v1 +kind: MutatingWebhookConfiguration +metadata: + creationTimestamp: null + name: mutating-webhook-configuration +webhooks: +- admissionReviewVersions: + - v1 + clientConfig: + service: + name: webhook-service + namespace: system + path: /mutate-v1-pod + failurePolicy: Ignore + name: pods.credentials-operator.otterize.com + rules: + - apiGroups: + - "" + apiVersions: + - v1 + operations: + - CREATE + - UPDATE + resources: + - pods + sideEffects: NoneOnDryRun diff --git a/src/operator/controllers/metadata/annotations.go b/src/operator/controllers/metadata/annotations.go index 939828d..a9ecb99 100644 --- a/src/operator/controllers/metadata/annotations.go +++ b/src/operator/controllers/metadata/annotations.go @@ -16,6 +16,10 @@ const ( // and IAM roles ServiceAccountAWSRoleARNAnnotation = "eks.amazonaws.com/role-arn" + // OtterizeServiceAccountAWSRoleARNAnnotation is used to update a Pod in the mutating webhook with the role ARN + // so that reinvocation is triggered for the EKS pod identity mutating webhook. + OtterizeServiceAccountAWSRoleARNAnnotation = "credentials-operator.otterize.com/eks-role-arn" + // DNSNamesAnnotation is a comma-separated list of additional dns names to be registered as part of the // SPIRE-server entry and encoded into the certificate data DNSNamesAnnotation = "credentials-operator.otterize.com/dns-names" diff --git a/src/operator/controllers/metadata/labels.go b/src/operator/controllers/metadata/labels.go index e744126..16546fe 100644 --- a/src/operator/controllers/metadata/labels.go +++ b/src/operator/controllers/metadata/labels.go @@ -12,5 +12,5 @@ const ( SecretTypeLabel = "credentials-operator.otterize.com/secret-type" // OtterizeServiceAccountLabel is used to label service accounts generated by the credentials-operator - OtterizeServiceAccountLabel = "credentials-operator.otterize.com/service-account" + OtterizeServiceAccountLabel = "credentials-operator.otterize.com/service-account-managed" ) diff --git a/src/operator/controllers/service_account_pod/service_account_pod_reconciler.go b/src/operator/controllers/service_account_pod/service_account_pod_reconciler.go deleted file mode 100644 index 622cc33..0000000 --- a/src/operator/controllers/service_account_pod/service_account_pod_reconciler.go +++ /dev/null @@ -1,96 +0,0 @@ -package service_account_pod - -import ( - "context" - "github.com/otterize/credentials-operator/src/controllers/metadata" - "github.com/otterize/intents-operator/src/shared/awsagent" - "github.com/samber/lo" - "github.com/sirupsen/logrus" - v1 "k8s.io/api/core/v1" - apierrors "k8s.io/apimachinery/pkg/api/errors" - "k8s.io/apimachinery/pkg/runtime" - "k8s.io/apimachinery/pkg/types" - "k8s.io/client-go/tools/record" - ctrl "sigs.k8s.io/controller-runtime" - "sigs.k8s.io/controller-runtime/pkg/client" - "sigs.k8s.io/controller-runtime/pkg/controller" -) - -const ( - ReasonGetServiceAccountFailed = "GetServiceAccountFailed" - ReasonCreatingServiceAccountFailed = "ServiceAccountCreationFailed" - ReasonServiceAccountUpdated = "ServiceAccountUpdated" - ReasonServiceAccountUpdateFailed = "ServiceAccountUpdateFailed" -) - -type PodServiceAccountReconciler struct { - client client.Client - scheme *runtime.Scheme - recorder record.EventRecorder - awsAgent *awsagent.Agent -} - -func NewPodServiceAccountReconciler(client client.Client, scheme *runtime.Scheme, eventRecorder record.EventRecorder, awsAgent *awsagent.Agent) *PodServiceAccountReconciler { - return &PodServiceAccountReconciler{ - client: client, - scheme: scheme, - awsAgent: awsAgent, - recorder: eventRecorder, - } -} - -func (r *PodServiceAccountReconciler) SetupWithManager(mgr ctrl.Manager) error { - return ctrl.NewControllerManagedBy(mgr). - WithOptions(controller.Options{RecoverPanic: lo.ToPtr(true)}). - For(&v1.Pod{}). - Complete(r) -} - -func (e *PodServiceAccountReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) { - var pod v1.Pod - err := e.client.Get(ctx, req.NamespacedName, &pod) - if err != nil { - if apierrors.IsNotFound(err) { - return ctrl.Result{}, nil - } - return ctrl.Result{}, err - } - - if pod.Annotations == nil { - return ctrl.Result{}, nil - } - _, annotationExists := pod.Annotations[metadata.CreateAWSRoleAnnotation] - if !annotationExists { - logrus.Debugf("pod %v doesn't have create AWS IAM role annotation, skipping", pod) - return ctrl.Result{}, nil - } - - serviceAccount := v1.ServiceAccount{} - err = e.client.Get(ctx, types.NamespacedName{Namespace: pod.Namespace, Name: pod.Spec.ServiceAccountName}, &serviceAccount) - - if err != nil { - e.recorder.Eventf(&pod, v1.EventTypeWarning, ReasonGetServiceAccountFailed, "Failed getting service account: %s for pod: %v", pod.Spec.ServiceAccountName, pod) - return ctrl.Result{}, err - } - - logrus.Debugf("service account %s exists, Updating it", pod.Spec.ServiceAccountName) - updatedServiceAccount := serviceAccount.DeepCopy() - if updatedServiceAccount.Labels == nil { - updatedServiceAccount.Labels = make(map[string]string) - } - previousServiceAccountValue, ok := serviceAccount.Labels[metadata.OtterizeServiceAccountLabel] - if !ok || previousServiceAccountValue != pod.Spec.ServiceAccountName { - updatedServiceAccount.Labels[metadata.OtterizeServiceAccountLabel] = pod.Spec.ServiceAccountName - err := e.client.Patch(ctx, updatedServiceAccount, client.MergeFrom(&serviceAccount)) - if err != nil { - if apierrors.IsConflict(err) { - return ctrl.Result{Requeue: true}, nil - } - e.recorder.Eventf(&pod, v1.EventTypeWarning, ReasonServiceAccountUpdateFailed, "failed to update pre-existing service account with Otterize label: %s", err.Error()) - return ctrl.Result{}, err - } - e.recorder.Eventf(&pod, v1.EventTypeNormal, ReasonServiceAccountUpdated, "service account %s already exists updated labels, labeling", pod.Spec.ServiceAccountName) - } - - return ctrl.Result{}, nil -} diff --git a/src/operator/controllers/service_account_pod/service_account_pod_reconciler_test.go b/src/operator/controllers/service_account_pod/service_account_pod_reconciler_test.go deleted file mode 100644 index e42b0af..0000000 --- a/src/operator/controllers/service_account_pod/service_account_pod_reconciler_test.go +++ /dev/null @@ -1,127 +0,0 @@ -package service_account_pod - -import ( - "context" - "fmt" - "github.com/otterize/credentials-operator/src/controllers/metadata" - mock_client "github.com/otterize/credentials-operator/src/mocks/controller-runtime/client" - mock_record "github.com/otterize/credentials-operator/src/mocks/eventrecorder" - "github.com/stretchr/testify/suite" - "go.uber.org/mock/gomock" - v1 "k8s.io/api/core/v1" - k8serrors "k8s.io/apimachinery/pkg/api/errors" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/runtime" - "k8s.io/apimachinery/pkg/types" - utilruntime "k8s.io/apimachinery/pkg/util/runtime" - clientgoscheme "k8s.io/client-go/kubernetes/scheme" - "net/http" - "reflect" - ctrl "sigs.k8s.io/controller-runtime" - "sigs.k8s.io/controller-runtime/pkg/client" - "testing" -) - -type serviceAccountMatcher struct { - Name string - Namespace string - Labels map[string]string -} - -func (m *serviceAccountMatcher) String() string { - return fmt.Sprintf("expected Name: %s Namespace: %s Labels: %s", m.Name, m.Namespace, m.Labels) -} - -func (m *serviceAccountMatcher) Matches(x interface{}) bool { - sa := x.(*v1.ServiceAccount) - return sa.Name == m.Name && sa.Namespace == m.Namespace && reflect.DeepEqual(m.Labels, sa.Labels) -} - -type PodServiceAccountEnsurerSuite struct { - suite.Suite - controller *gomock.Controller - client *mock_client.MockClient - ServiceAccountReconciler *PodServiceAccountReconciler - mockEventRecorder *mock_record.MockEventRecorder -} - -func (s *PodServiceAccountEnsurerSuite) SetupTest() { - s.controller = gomock.NewController(s.T()) - s.client = mock_client.NewMockClient(s.controller) - - scheme := runtime.NewScheme() - utilruntime.Must(clientgoscheme.AddToScheme(scheme)) - s.client.EXPECT().Scheme().Return(scheme).AnyTimes() - s.mockEventRecorder = mock_record.NewMockEventRecorder(s.controller) - s.ServiceAccountReconciler = NewPodServiceAccountReconciler(s.client, scheme, s.mockEventRecorder, nil) -} - -func (s *PodServiceAccountEnsurerSuite) TestErrorWhenSADoesntExist() { - serviceAccountName := "cool.name" - annotations := map[string]string{metadata.CreateAWSRoleAnnotation: serviceAccountName} - namespace := "namespace" - s.client.EXPECT().Get(gomock.Any(), gomock.Eq(types.NamespacedName{Name: serviceAccountName, Namespace: namespace}), gomock.AssignableToTypeOf(&v1.ServiceAccount{})). - Return( - &k8serrors.StatusError{ - ErrStatus: metav1.Status{Status: metav1.StatusFailure, Code: http.StatusNotFound, Reason: metav1.StatusReasonNotFound}, - }) - - s.mockEventRecorder.EXPECT().Eventf(gomock.Any(), gomock.Eq(v1.EventTypeWarning), gomock.Eq(ReasonGetServiceAccountFailed), gomock.Any(), gomock.Any()) - pod := v1.Pod{ObjectMeta: metav1.ObjectMeta{Name: "Pod", Namespace: namespace, Annotations: annotations}, Spec: v1.PodSpec{ServiceAccountName: serviceAccountName}} - - s.client.EXPECT(). - Get(gomock.Any(), gomock.Eq(types.NamespacedName{Name: pod.Name, Namespace: pod.Namespace}), gomock.AssignableToTypeOf(&v1.Pod{})). - Do(func(_, _ any, podPtr *v1.Pod, _ ...interface{}) { - *podPtr = pod - }) - - res, err := s.ServiceAccountReconciler.Reconcile(context.Background(), ctrl.Request{NamespacedName: types.NamespacedName{Name: pod.Name, Namespace: pod.Namespace}}) - s.Require().Error(err) - s.Require().True(res.IsZero()) - -} - -func (s *PodServiceAccountEnsurerSuite) TestUpdateWhenFound() { - serviceAccountName := "cool.name" - annotations := map[string]string{metadata.CreateAWSRoleAnnotation: serviceAccountName} - namespace := "namespace" - serviceAccount := v1.ServiceAccount{ObjectMeta: metav1.ObjectMeta{ - Name: serviceAccountName, - Namespace: namespace, - }} - s.client.EXPECT().Get(gomock.Any(), gomock.Eq(types.NamespacedName{Name: serviceAccountName, Namespace: namespace}), gomock.AssignableToTypeOf(&v1.ServiceAccount{})). - Do(func(_, _ any, saPtr *v1.ServiceAccount, _ ...any) { *saPtr = serviceAccount }) - - s.client.EXPECT().Patch(gomock.Any(), &serviceAccountMatcher{Name: serviceAccountName, Namespace: namespace, Labels: map[string]string{metadata.OtterizeServiceAccountLabel: serviceAccountName}}, gomock.AssignableToTypeOf(client.MergeFrom(&serviceAccount))) - s.mockEventRecorder.EXPECT().Eventf(gomock.Any(), gomock.Eq(v1.EventTypeNormal), gomock.Eq(ReasonServiceAccountUpdated), gomock.Any(), gomock.Any()) - pod := v1.Pod{ObjectMeta: metav1.ObjectMeta{Name: "Pod", Namespace: namespace, Annotations: annotations}, Spec: v1.PodSpec{ - ServiceAccountName: serviceAccountName, - }} - - s.client.EXPECT(). - Get(gomock.Any(), gomock.Eq(types.NamespacedName{Name: pod.Name, Namespace: pod.Namespace}), gomock.AssignableToTypeOf(&v1.Pod{})). - Do(func(_, _ any, podPtr *v1.Pod, _ ...interface{}) { - *podPtr = pod - }) - - res, err := s.ServiceAccountReconciler.Reconcile(context.Background(), ctrl.Request{NamespacedName: types.NamespacedName{Name: pod.Name, Namespace: pod.Namespace}}) - s.Require().NoError(err) - s.Require().True(res.IsZero()) - -} - -func (s *PodServiceAccountEnsurerSuite) TestDoNothingWhenNoAnnotation() { - pod := v1.Pod{ObjectMeta: metav1.ObjectMeta{Name: "Pod", Namespace: "namespace"}} - s.client.EXPECT(). - Get(gomock.Any(), gomock.Eq(types.NamespacedName{Name: pod.Name, Namespace: pod.Namespace}), gomock.AssignableToTypeOf(&v1.Pod{})). - Do(func(_, _ any, podPtr *v1.Pod, _ ...interface{}) { - *podPtr = pod - }) - res, err := s.ServiceAccountReconciler.Reconcile(context.Background(), ctrl.Request{NamespacedName: types.NamespacedName{Name: pod.Name, Namespace: pod.Namespace}}) - s.Require().NoError(err) - s.Require().True(res.IsZero()) -} - -func TestPodServiceAccountEnsurerSuite(t *testing.T) { - suite.Run(t, new(PodServiceAccountEnsurerSuite)) -} diff --git a/src/operator/controllers/serviceaccount/serviceaccount_controller.go b/src/operator/controllers/serviceaccount/serviceaccount_controller.go index 65c8287..8f7f818 100644 --- a/src/operator/controllers/serviceaccount/serviceaccount_controller.go +++ b/src/operator/controllers/serviceaccount/serviceaccount_controller.go @@ -2,6 +2,7 @@ package serviceaccount import ( "context" + "fmt" "github.com/aws/aws-sdk-go-v2/service/iam/types" "github.com/otterize/credentials-operator/src/controllers/metadata" "github.com/otterize/intents-operator/src/shared/awsagent" @@ -56,26 +57,25 @@ func (r *ServiceAccountReconciler) Reconcile(ctx context.Context, req ctrl.Reque return ctrl.Result{}, err } - if r.awsAgent != nil { - modified, role, err := r.reconcileAWSRole(ctx, &serviceAccount) + shouldUpdateAnnotation, role, err := r.reconcileAWSRole(ctx, &serviceAccount) - if err != nil { - return ctrl.Result{}, err - } - - if modified { - if serviceAccount.Annotations == nil { - serviceAccount.Annotations = make(map[string]string) - } + if err != nil { + return ctrl.Result{}, err + } - serviceAccount.Annotations[metadata.ServiceAccountAWSRoleARNAnnotation] = *role.Arn - err = r.Client.Update(ctx, &serviceAccount) + if shouldUpdateAnnotation { + updatedServiceAccount := serviceAccount.DeepCopy() + if updatedServiceAccount.Annotations == nil { + updatedServiceAccount.Annotations = make(map[string]string) + } - if err != nil { - return ctrl.Result{}, err + updatedServiceAccount.Annotations[metadata.ServiceAccountAWSRoleARNAnnotation] = *role.Arn + err = r.Client.Patch(ctx, updatedServiceAccount, client.MergeFrom(&serviceAccount)) + if err != nil { + if apierrors.IsConflict(err) { + return ctrl.Result{Requeue: true}, nil } - - return ctrl.Result{Requeue: true}, nil + return ctrl.Result{}, err } } @@ -87,46 +87,48 @@ func (r *ServiceAccountReconciler) Reconcile(ctx context.Context, req ctrl.Reque // - modified: if AWS state was modified (and the ServiceAccount should be re-queued) // - role: the AWS IAM role // - err -func (r *ServiceAccountReconciler) reconcileAWSRole(ctx context.Context, serviceAccount *corev1.ServiceAccount) (bool, *types.Role, error) { +func (r *ServiceAccountReconciler) reconcileAWSRole(ctx context.Context, serviceAccount *corev1.ServiceAccount) (updateAnnotation bool, role *types.Role, err error) { logger := logrus.WithFields(logrus.Fields{"serviceAccount": serviceAccount.Name, "namespace": serviceAccount.Namespace}) if !hasOtterizeServiceAccountLabel(serviceAccount) { - logger.Debug("serviceAccount not labelled with credentials-operator.otterize.com/service-account, skipping") + logger.Debug("serviceAccount not labeled with credentials-operator.otterize.com/service-account, skipping") return false, nil, nil } - if hasAWSAnnotation(serviceAccount) { + if roleARN, ok := hasAWSAnnotation(serviceAccount); ok { + generatedRoleARN := r.awsAgent.GenerateRoleARN(serviceAccount.Namespace, serviceAccount.Name) found, role, err := r.awsAgent.GetOtterizeRole(ctx, serviceAccount.Namespace, serviceAccount.Name) if err != nil { - logger.WithError(err).Error("failed checking for AWS role") - return true, nil, err + return false, nil, fmt.Errorf("failed getting AWS role: %w", err) } if found { + if generatedRoleARN != roleARN { + logger.WithField("arn", role.Arn).Debug("ServiceAccount AWS role exists, but annotation is misconfigured, should be updated") + return true, role, nil + } logger.WithField("arn", role.Arn).Debug("ServiceAccount has matching AWS role") return false, role, nil } } - role, err := r.awsAgent.CreateOtterizeIAMRole(ctx, serviceAccount.Namespace, serviceAccount.Name) - + role, err = r.awsAgent.CreateOtterizeIAMRole(ctx, serviceAccount.Namespace, serviceAccount.Name) if err != nil { - logger.WithError(err).Error("failed creating AWS role for ServiceAccount") - return true, nil, err + return true, nil, fmt.Errorf("failed creating AWS role for service account: %w", err) } logger.WithField("arn", role.Arn).Info("created AWS role for ServiceAccount") return true, role, nil } -func hasAWSAnnotation(serviceAccount *corev1.ServiceAccount) bool { +func hasAWSAnnotation(serviceAccount *corev1.ServiceAccount) (string, bool) { if serviceAccount.Annotations == nil { - return false + return "", false } - _, ok := serviceAccount.Annotations[metadata.ServiceAccountAWSRoleARNAnnotation] - return ok + roleARN, ok := serviceAccount.Annotations[metadata.ServiceAccountAWSRoleARNAnnotation] + return roleARN, ok } func hasOtterizeServiceAccountLabel(serviceAccount *corev1.ServiceAccount) bool { diff --git a/src/operator/controllers/webhooks/pod_webhook.go b/src/operator/controllers/webhooks/pod_webhook.go new file mode 100644 index 0000000..6c9bdfd --- /dev/null +++ b/src/operator/controllers/webhooks/pod_webhook.go @@ -0,0 +1,124 @@ +package webhooks + +import ( + "context" + "encoding/json" + "fmt" + "github.com/otterize/credentials-operator/src/controllers/metadata" + "github.com/otterize/intents-operator/src/shared/awsagent" + "github.com/sirupsen/logrus" + corev1 "k8s.io/api/core/v1" + k8serrors "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/types" + "net/http" + "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/manager" + "sigs.k8s.io/controller-runtime/pkg/webhook/admission" + "time" +) + +// +kubebuilder:webhook:path=/mutate-v1-pod,mutating=true,failurePolicy=ignore,groups="",sideEffects=NoneOnDryRun,resources=pods,verbs=create;update,versions=v1,admissionReviewVersions=v1,name=pods.credentials-operator.otterize.com + +type PodWebhookAnnotatesPodServiceAccount struct { + client client.Client + decoder *admission.Decoder + awsAgent *awsagent.Agent +} + +func NewPodWebhookAnnotatesPodServiceAccount(mgr manager.Manager, awsAgent *awsagent.Agent) *PodWebhookAnnotatesPodServiceAccount { + return &PodWebhookAnnotatesPodServiceAccount{ + client: mgr.GetClient(), + decoder: admission.NewDecoder(mgr.GetScheme()), + awsAgent: awsAgent, + } +} + +func (a *PodWebhookAnnotatesPodServiceAccount) handleOnce(ctx context.Context, pod corev1.Pod, dryRun bool) (outputPod corev1.Pod, patched bool, successMsg string, err error) { + if pod.Annotations == nil { + return pod, false, "no create AWS role annotation - no modifications made", nil + } + _, annotationExists := pod.Annotations[metadata.CreateAWSRoleAnnotation] + if !annotationExists { + logrus.Debugf("pod %v doesn't have create AWS IAM role annotation, skipping", pod) + return pod, false, "no create AWS role annotation - no modifications made", nil + } + + var serviceAccount corev1.ServiceAccount + err = a.client.Get(ctx, types.NamespacedName{ + Namespace: pod.Namespace, + Name: pod.Spec.ServiceAccountName, + }, &serviceAccount) + if err != nil { + return corev1.Pod{}, false, "", fmt.Errorf("could not get service account: %w", err) + } + + roleArn := a.awsAgent.GenerateRoleARN(serviceAccount.Namespace, serviceAccount.Name) + + updatedServiceAccount := serviceAccount.DeepCopy() + + if updatedServiceAccount.Annotations == nil { + updatedServiceAccount.Annotations = make(map[string]string) + } + + // we don't actually create the role here, so that the webhook returns quickly - a ServiceAccount reconciler takes care of it for us. + updatedServiceAccount.Annotations[metadata.ServiceAccountAWSRoleARNAnnotation] = roleArn + updatedServiceAccount.Labels[metadata.OtterizeServiceAccountLabel] = "true" + if !dryRun { + err = a.client.Patch(ctx, updatedServiceAccount, client.MergeFrom(&serviceAccount)) + if err != nil { + return corev1.Pod{}, false, "", fmt.Errorf("could not update service account: %w", err) + } + } + + // add label to trigger reinvocation for AWS pod reconciler + if pod.Annotations == nil { + pod.Annotations = make(map[string]string) + } + + pod.Annotations[metadata.OtterizeServiceAccountAWSRoleARNAnnotation] = roleArn + return pod, true, "pod and service account updated to create AWS role", nil +} + +// dryRun: should not cause any modifications except to the Pod in the request. +func (a *PodWebhookAnnotatesPodServiceAccount) handleWithRetriesOnConflict(ctx context.Context, pod corev1.Pod, dryRun bool) (outputPod corev1.Pod, patched bool, successMsg string, err error) { + for attempt := 0; attempt < 3; attempt++ { + logrus.Debugf("Handling pod '%s' in namespace '%s' (attempt %d out of %d)", pod.Name, pod.Namespace, attempt+1, 3) + outputPod, patched, successMsg, err = a.handleOnce(ctx, *pod.DeepCopy(), dryRun) + if err != nil { + if k8serrors.IsConflict(err) { + logrus.WithError(err).Errorf("failed to handle pod '%s' in namespace '%s' due to conflict, retrying in 1 second (attempt %d out of %d)", pod.Name, pod.Namespace, attempt+1, 3) + time.Sleep(1 * time.Second) + continue + } + return corev1.Pod{}, false, "", err + } + return outputPod, patched, successMsg, nil + } + if err != nil { + return corev1.Pod{}, false, "", err + } + panic("unreachable - must have received error or it would have exited in the for loop") +} + +func (a *PodWebhookAnnotatesPodServiceAccount) Handle(ctx context.Context, req admission.Request) admission.Response { + pod := corev1.Pod{} + err := a.decoder.Decode(req, &pod) + if err != nil { + return admission.Errored(http.StatusBadRequest, err) + } + + pod, patched, successMsg, err := a.handleWithRetriesOnConflict(ctx, pod, req.DryRun != nil && *req.DryRun) + if err != nil { + return admission.Errored(http.StatusInternalServerError, err) + } + + if !patched { + return admission.Allowed(successMsg) + } + + marshaledPod, err := json.Marshal(pod) + if err != nil { + return admission.Errored(http.StatusInternalServerError, err) + } + return admission.PatchResponseFromRaw(req.Object.Raw, marshaledPod) +} diff --git a/src/operator/go.mod b/src/operator/go.mod index bf5ad98..66fb83f 100644 --- a/src/operator/go.mod +++ b/src/operator/go.mod @@ -6,7 +6,7 @@ require ( github.com/Khan/genqlient v0.6.0 github.com/amit7itz/goset v1.2.1 github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a - github.com/aws/aws-sdk-go-v2/service/iam v1.22.5 + github.com/aws/aws-sdk-go-v2/service/iam v1.27.2 github.com/bombsimon/logrusr/v3 v3.0.0 github.com/cert-manager/cert-manager v1.12.3 github.com/otterize/intents-operator/src v0.0.0-20231029112047-8981c2356ed0 @@ -32,22 +32,22 @@ require ( github.com/Azure/go-ntlmssp v0.0.0-20220621081337-cb9428e4ac1e // indirect github.com/DataDog/datadog-go v3.2.0+incompatible // indirect github.com/Microsoft/go-winio v0.6.0 // indirect - github.com/agnivade/levenshtein v1.1.1 // indirect - github.com/alexflint/go-arg v1.4.2 // indirect - github.com/alexflint/go-scalar v1.0.0 // indirect github.com/armon/go-metrics v0.4.1 // indirect - github.com/aws/aws-sdk-go-v2 v1.21.0 // indirect - github.com/aws/aws-sdk-go-v2/config v1.18.42 // indirect - github.com/aws/aws-sdk-go-v2/credentials v1.13.40 // indirect - github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.13.11 // indirect - github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.41 // indirect - github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.35 // indirect - github.com/aws/aws-sdk-go-v2/internal/ini v1.3.43 // indirect - github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.35 // indirect - github.com/aws/aws-sdk-go-v2/service/sso v1.14.1 // indirect - github.com/aws/aws-sdk-go-v2/service/ssooidc v1.17.1 // indirect - github.com/aws/aws-sdk-go-v2/service/sts v1.22.0 // indirect - github.com/aws/smithy-go v1.14.2 // indirect + github.com/aws/aws-sdk-go-v2 v1.23.0 // indirect + github.com/aws/aws-sdk-go-v2/config v1.25.3 // indirect + github.com/aws/aws-sdk-go-v2/credentials v1.16.2 // indirect + github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.14.4 // indirect + github.com/aws/aws-sdk-go-v2/internal/configsources v1.2.3 // indirect + github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.5.3 // indirect + github.com/aws/aws-sdk-go-v2/internal/ini v1.7.1 // indirect + github.com/aws/aws-sdk-go-v2/service/ec2 v1.136.0 // indirect + github.com/aws/aws-sdk-go-v2/service/eks v1.33.1 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.10.1 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.10.3 // indirect + github.com/aws/aws-sdk-go-v2/service/sso v1.17.2 // indirect + github.com/aws/aws-sdk-go-v2/service/ssooidc v1.20.0 // indirect + github.com/aws/aws-sdk-go-v2/service/sts v1.25.3 // indirect + github.com/aws/smithy-go v1.17.0 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/blang/semver/v4 v4.0.0 // indirect github.com/cespare/xxhash/v2 v2.2.0 // indirect @@ -75,6 +75,7 @@ require ( github.com/hashicorp/hcl v1.0.1-0.20190430135223-99e2f22d1c94 // indirect github.com/imdario/mergo v0.3.13 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect + github.com/jmespath/go-jmespath v0.4.0 // indirect github.com/josharian/intern v1.0.0 // indirect github.com/json-iterator/go v1.1.12 // indirect github.com/magiconair/properties v1.8.6 // indirect @@ -135,3 +136,5 @@ require ( sigs.k8s.io/structured-merge-diff/v4 v4.2.3 // indirect sigs.k8s.io/yaml v1.3.0 // indirect ) + +replace github.com/otterize/intents-operator/src => ../../../intents-operator/src diff --git a/src/operator/go.sum b/src/operator/go.sum index 43bc625..4b3150b 100644 --- a/src/operator/go.sum +++ b/src/operator/go.sum @@ -49,17 +49,11 @@ github.com/Microsoft/go-winio v0.6.0 h1:slsWYD/zyx7lCXoZVlvQrj0hPTM1HI4+v1sIda2y github.com/Microsoft/go-winio v0.6.0/go.mod h1:cTAf44im0RAYeL23bpB+fzCyDH2MJiz2BO69KH/soAE= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/agnivade/levenshtein v1.0.1/go.mod h1:CURSv5d9Uaml+FovSIICkLbAUZ9S4RqaHDIsdSBg7lM= -github.com/agnivade/levenshtein v1.1.1 h1:QY8M92nrzkmr798gCo3kmMyqXFzdQVpxLlGPRBij0P8= -github.com/agnivade/levenshtein v1.1.1/go.mod h1:veldBMzWxcCG2ZvUTKD2kJNRdCk5hVbJomOvKkmgYbo= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= -github.com/alexflint/go-arg v1.4.2 h1:lDWZAXxpAnZUq4qwb86p/3rIJJ2Li81EoMbTMujhVa0= -github.com/alexflint/go-arg v1.4.2/go.mod h1:9iRbDxne7LcR/GSvEr7ma++GLpdIU1zrghf2y2768kM= -github.com/alexflint/go-scalar v1.0.0 h1:NGupf1XV/Xb04wXskDFzS0KWOLH632W/EO4fAFi+A70= -github.com/alexflint/go-scalar v1.0.0/go.mod h1:GpHzbCOZXEKMEcygYQ5n/aa4Aq84zbxjy3MxYW0gjYw= github.com/amit7itz/goset v1.2.1 h1:usFphDJfZgwnqfbKT8zI+2juuOgsZ6O8UA7NMRUVG7s= github.com/amit7itz/goset v1.2.1/go.mod h1:i8ni2YcxUMAwLBOkHWpy3glFviYdTcWqCvFgp91EMGI= github.com/andres-erbsen/clock v0.0.0-20160526145045-9e14626cd129 h1:MzBOUgng9orim59UnfUTLRjMpd09C5uEVQ6RPGeCaVI= @@ -67,37 +61,42 @@ github.com/andres-erbsen/clock v0.0.0-20160526145045-9e14626cd129/go.mod h1:rFgp github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883 h1:bvNMNQO63//z+xNgfBlViaCIJKLlCJ6/fmUseuG0wVQ= github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8= github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= -github.com/arbovm/levenshtein v0.0.0-20160628152529-48b4e1c0c4d0/go.mod h1:t2tdKJDJF9BV14lnkjHmOQgcvEKgtqs5a1N3LNdJhGE= github.com/armon/go-metrics v0.4.1 h1:hR91U9KYmb6bLBYLQjyM+3j+rcd/UhE+G78SFnF8gJA= github.com/armon/go-metrics v0.4.1/go.mod h1:E6amYzXo6aW1tqzoZGT755KkbgrJsSdpwZ+3JqfkOG4= github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a h1:idn718Q4B6AGu/h5Sxe66HYVdqdGu2l9Iebqhi/AEoA= github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY= -github.com/aws/aws-sdk-go-v2 v1.21.0 h1:gMT0IW+03wtYJhRqTVYn0wLzwdnK9sRMcxmtfGzRdJc= -github.com/aws/aws-sdk-go-v2 v1.21.0/go.mod h1:/RfNgGmRxI+iFOB1OeJUyxiU+9s88k3pfHvDagGEp0M= -github.com/aws/aws-sdk-go-v2/config v1.18.42 h1:28jHROB27xZwU0CB88giDSjz7M1Sba3olb5JBGwina8= -github.com/aws/aws-sdk-go-v2/config v1.18.42/go.mod h1:4AZM3nMMxwlG+eZlxvBKqwVbkDLlnN2a4UGTL6HjaZI= -github.com/aws/aws-sdk-go-v2/credentials v1.13.40 h1:s8yOkDh+5b1jUDhMBtngF6zKWLDs84chUk2Vk0c38Og= -github.com/aws/aws-sdk-go-v2/credentials v1.13.40/go.mod h1:VtEHVAAqDWASwdOqj/1huyT6uHbs5s8FUHfDQdky/Rs= -github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.13.11 h1:uDZJF1hu0EVT/4bogChk8DyjSF6fof6uL/0Y26Ma7Fg= -github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.13.11/go.mod h1:TEPP4tENqBGO99KwVpV9MlOX4NSrSLP8u3KRy2CDwA8= -github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.41 h1:22dGT7PneFMx4+b3pz7lMTRyN8ZKH7M2cW4GP9yUS2g= -github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.41/go.mod h1:CrObHAuPneJBlfEJ5T3szXOUkLEThaGfvnhTf33buas= -github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.35 h1:SijA0mgjV8E+8G45ltVHs0fvKpTj8xmZJ3VwhGKtUSI= -github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.35/go.mod h1:SJC1nEVVva1g3pHAIdCp7QsRIkMmLAgoDquQ9Rr8kYw= -github.com/aws/aws-sdk-go-v2/internal/ini v1.3.43 h1:g+qlObJH4Kn4n21g69DjspU0hKTjWtq7naZ9OLCv0ew= -github.com/aws/aws-sdk-go-v2/internal/ini v1.3.43/go.mod h1:rzfdUlfA+jdgLDmPKjd3Chq9V7LVLYo1Nz++Wb91aRo= -github.com/aws/aws-sdk-go-v2/service/iam v1.22.5 h1:qGv+oW4uV1T3kbE9uSYEfdZbo38OqxgRxxfStfDr4BU= -github.com/aws/aws-sdk-go-v2/service/iam v1.22.5/go.mod h1:8lyPrjQczmx72ac9s82zTjf9xLqs7uuFMG9TVEZ07XU= -github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.35 h1:CdzPW9kKitgIiLV1+MHobfR5Xg25iYnyzWZhyQuSlDI= -github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.35/go.mod h1:QGF2Rs33W5MaN9gYdEQOBBFPLwTZkEhRwI33f7KIG0o= -github.com/aws/aws-sdk-go-v2/service/sso v1.14.1 h1:YkNzx1RLS0F5qdf9v1Q8Cuv9NXCL2TkosOxhzlUPV64= -github.com/aws/aws-sdk-go-v2/service/sso v1.14.1/go.mod h1:fIAwKQKBFu90pBxx07BFOMJLpRUGu8VOzLJakeY+0K4= -github.com/aws/aws-sdk-go-v2/service/ssooidc v1.17.1 h1:8lKOidPkmSmfUtiTgtdXWgaKItCZ/g75/jEk6Ql6GsA= -github.com/aws/aws-sdk-go-v2/service/ssooidc v1.17.1/go.mod h1:yygr8ACQRY2PrEcy3xsUI357stq2AxnFM6DIsR9lij4= -github.com/aws/aws-sdk-go-v2/service/sts v1.22.0 h1:s4bioTgjSFRwOoyEFzAVCmFmoowBgjTR8gkrF/sQ4wk= -github.com/aws/aws-sdk-go-v2/service/sts v1.22.0/go.mod h1:VC7JDqsqiwXukYEDjoHh9U0fOJtNWh04FPQz4ct4GGU= -github.com/aws/smithy-go v1.14.2 h1:MJU9hqBGbvWZdApzpvoF2WAIJDbtjK2NDJSiJP7HblQ= -github.com/aws/smithy-go v1.14.2/go.mod h1:Tg+OJXh4MB2R/uN61Ko2f6hTZwB/ZYGOtib8J3gBHzA= +github.com/aws/aws-sdk-go-v2 v1.23.0 h1:PiHAzmiQQr6JULBUdvR8fKlA+UPKLT/8KbiqpFBWiAo= +github.com/aws/aws-sdk-go-v2 v1.23.0/go.mod h1:i1XDttT4rnf6vxc9AuskLc6s7XBee8rlLilKlc03uAA= +github.com/aws/aws-sdk-go-v2/config v1.25.3 h1:E4m9LbwJOoncDNt3e9MPLbz/saxWcGUlZVBydydD6+8= +github.com/aws/aws-sdk-go-v2/config v1.25.3/go.mod h1:tAByZy03nH5jcq0vZmkcVoo6tRzRHEwSFx3QW4NmDw8= +github.com/aws/aws-sdk-go-v2/credentials v1.16.2 h1:0sdZ5cwfOAipTzZ7eOL0gw4LAhk/RZnTa16cDqIt8tg= +github.com/aws/aws-sdk-go-v2/credentials v1.16.2/go.mod h1:sDdvGhXrSVT5yzBDR7qXz+rhbpiMpUYfF3vJ01QSdrc= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.14.4 h1:9wKDWEjwSnXZre0/O3+ZwbBl1SmlgWYBbrTV10X/H1s= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.14.4/go.mod h1:t4i+yGHMCcUNIX1x7YVYa6bH/Do7civ5I6cG/6PMfyA= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.2.3 h1:DUwbD79T8gyQ23qVXFUthjzVMTviSHi3y4z58KvghhM= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.2.3/go.mod h1:7sGSz1JCKHWWBHq98m6sMtWQikmYPpxjqOydDemiVoM= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.5.3 h1:AplLJCtIaUZDCbr6+gLYdsYNxne4iuaboJhVt9d+WXI= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.5.3/go.mod h1:ify42Rb7nKeDDPkFjKn7q1bPscVPu/+gmHH8d2c+anU= +github.com/aws/aws-sdk-go-v2/internal/ini v1.7.1 h1:uR9lXYjdPX0xY+NhvaJ4dD8rpSRz5VY81ccIIoNG+lw= +github.com/aws/aws-sdk-go-v2/internal/ini v1.7.1/go.mod h1:6fQQgfuGmw8Al/3M2IgIllycxV7ZW7WCdVSqfBeUiCY= +github.com/aws/aws-sdk-go-v2/service/ec2 v1.136.0 h1:nZPVFkGojUUJupKJzaCKE07LaFDO3Tto1U69F8JipsI= +github.com/aws/aws-sdk-go-v2/service/ec2 v1.136.0/go.mod h1:xYJZQIo/YZxEbeBxUYRQJTCJ924EuKtDfrhVx76yzOE= +github.com/aws/aws-sdk-go-v2/service/eks v1.33.1 h1:zRB7CTeejJmBpdpzrBkciNLMpg8T+06EvGA/H4Kkvcw= +github.com/aws/aws-sdk-go-v2/service/eks v1.33.1/go.mod h1:23btAyMrfTvG2zh/3+CZJ1c2eYWiVWP6tPRJwC67sk8= +github.com/aws/aws-sdk-go-v2/service/iam v1.27.2 h1:Z3a5I5kKGsuVW4kbrtHVnLGUHpEpo19zFyo6dzP2WCM= +github.com/aws/aws-sdk-go-v2/service/iam v1.27.2/go.mod h1:CYRyr95Q57xVvrcKJu3vw4jVVCZhmY1SyugM+EWXlzI= +github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.10.1 h1:rpkF4n0CyFcrJUG/rNNohoTmhtWlFTRI4BsZOh9PvLs= +github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.10.1/go.mod h1:l9ymW25HOqymeU2m1gbUQ3rUIsTwKs8gYHXkqDQUhiI= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.10.3 h1:kJOolE8xBAD13xTCgOakByZkyP4D/owNmvEiioeUNAg= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.10.3/go.mod h1:Owv1I59vaghv1Ax8zz8ELY8DN7/Y0rGS+WWAmjgi950= +github.com/aws/aws-sdk-go-v2/service/sso v1.17.2 h1:V47N5eKgVZoRSvx2+RQ0EpAEit/pqOhqeSQFiS4OFEQ= +github.com/aws/aws-sdk-go-v2/service/sso v1.17.2/go.mod h1:/pE21vno3q1h4bbhUOEi+6Zu/aT26UK2WKkDXd+TssQ= +github.com/aws/aws-sdk-go-v2/service/ssooidc v1.20.0 h1:/XiEU7VIFcVWRDQLabyrSjBoKIm8UkYgsvWDuFW8Img= +github.com/aws/aws-sdk-go-v2/service/ssooidc v1.20.0/go.mod h1:dWqm5G767qwKPuayKfzm4rjzFmVjiBFbOJrpSPnAMDs= +github.com/aws/aws-sdk-go-v2/service/sts v1.25.3 h1:M2w4kiMGJCCM6Ljmmx/l6mmpfa3gPJVpBencfnsgvqs= +github.com/aws/aws-sdk-go-v2/service/sts v1.25.3/go.mod h1:4EqRHDCKP78hq3zOnmFXu5k0j4bXbRFfCh/zQ6KnEfQ= +github.com/aws/smithy-go v1.17.0 h1:wWJD7LX6PBV6etBUwO0zElG0nWN9rUhp0WdYeHSHAaI= +github.com/aws/smithy-go v1.17.0/go.mod h1:NukqUGpCZIILqqiV0NIjeFh24kd/FAa4beRb6nbIUPE= github.com/benbjohnson/clock v1.1.0 h1:Q92kusRqC1XV2MjkWETPvjJVqKetz1OzxZB7mHJLju8= github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= @@ -137,7 +136,6 @@ github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ3 github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/dgryski/trifles v0.0.0-20200323201526-dd97f9abfb48/go.mod h1:if7Fbed8SFyPtHLHbg49SI7NAdJiC5WIA09pe59rfAA= github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE= github.com/emicklei/go-restful/v3 v3.10.2 h1:hIovbnmBTLjHXkqEBUz3HGpXZdM7ZrE9fJIZIqlJLqE= github.com/emicklei/go-restful/v3 v3.10.2/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= @@ -236,7 +234,6 @@ github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= @@ -286,7 +283,9 @@ github.com/imdario/mergo v0.3.13/go.mod h1:4lJ1jqUDcsbIECGy0RUJAXNIhg+6ocWgb1ALK github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= +github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg= github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= +github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGwWFoC7ycTf1rcQZHOlsJ6N8= github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U= github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= @@ -340,8 +339,6 @@ github.com/onsi/ginkgo/v2 v2.9.5 h1:+6Hr4uxzP4XIUyAkg61dWBw8lb/gc4/X5luuxN/EC+Q= github.com/onsi/ginkgo/v2 v2.9.5/go.mod h1:tvAoo1QUJwNEU2ITftXTpR7R1RbCzoZUOs3RonqW57k= github.com/onsi/gomega v1.27.7 h1:fVih9JD6ogIiHUN6ePK7HJidyEDpWGVB5mzM7cWNXoU= github.com/onsi/gomega v1.27.7/go.mod h1:1p8OOlwo2iUUDsHnOrjE5UKYJ+e3W8eQ3qSlRahPmr4= -github.com/otterize/intents-operator/src v0.0.0-20231029112047-8981c2356ed0 h1:+lN2DHZSscxP6k9H03OqFcdZ9UrBmmSaJ0U6DFt4PTc= -github.com/otterize/intents-operator/src v0.0.0-20231029112047-8981c2356ed0/go.mod h1:S5BmgcbUKAW8p7DdxTr+a9wmLVSy+f8eojOaAWnpZ6I= github.com/pascaldekloe/goe v0.1.0 h1:cBOtyMzM9HTpWjXfbbunk26uA6nG3a8n06Wieeh0MwY= github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= github.com/pavlo-v-chernykh/keystore-go/v4 v4.4.1 h1:FyBdsRqqHH4LctMLL+BL2oGO+ONcIPwn96ctofCVtNE= @@ -864,6 +861,10 @@ honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWh honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= +istio.io/api v0.0.0-20230310175855-3be9c0870417 h1:AuOCDeRxGZ729QlPjaFQtBwjD9HHBY0P9Z19FSmSnTU= +istio.io/api v0.0.0-20230310175855-3be9c0870417/go.mod h1:q3bvmBQjuI+OKNn9693bhGq3Pk+rECjfs3OpPWInHY0= +istio.io/client-go v1.17.1 h1:W0kQXYCzIluA/20zLzxeNF7bNMJXXArmGYRt/MIg2io= +istio.io/client-go v1.17.1/go.mod h1:mLTRYYFxHctzUbt8Iclgj+Sueq34+qC2ZEJTn6BxRuE= k8s.io/api v0.27.2 h1:+H17AJpUMvl+clT+BPnKf0E3ksMAzoBBg7CntpSuADo= k8s.io/api v0.27.2/go.mod h1:ENmbocXfBT2ADujUXcBhHV55RIT31IIEvkntP6vZKS4= k8s.io/apiextensions-apiserver v0.27.2 h1:iwhyoeS4xj9Y7v8YExhUwbVuBhMr3Q4bd/laClBV6Bo= diff --git a/src/operator/main.go b/src/operator/main.go index 4aa9601..25868ea 100644 --- a/src/operator/main.go +++ b/src/operator/main.go @@ -28,13 +28,14 @@ import ( "github.com/otterize/credentials-operator/src/controllers/otterizeclient" "github.com/otterize/credentials-operator/src/controllers/poduserpassword" "github.com/otterize/credentials-operator/src/controllers/secrets" - "github.com/otterize/credentials-operator/src/controllers/service_account_pod" "github.com/otterize/credentials-operator/src/controllers/serviceaccount" "github.com/otterize/credentials-operator/src/controllers/spireclient" "github.com/otterize/credentials-operator/src/controllers/spireclient/bundles" "github.com/otterize/credentials-operator/src/controllers/spireclient/entries" "github.com/otterize/credentials-operator/src/controllers/spireclient/svids" "github.com/otterize/credentials-operator/src/controllers/tls_pod" + "github.com/otterize/credentials-operator/src/controllers/webhooks" + operatorwebhooks "github.com/otterize/intents-operator/src/operator/webhooks" "github.com/otterize/intents-operator/src/shared/awsagent" "github.com/otterize/intents-operator/src/shared/serviceidresolver" "github.com/otterize/intents-operator/src/shared/telemetries/telemetriesgql" @@ -43,6 +44,7 @@ import ( "github.com/spiffe/go-spiffe/v2/workloadapi" "golang.org/x/exp/slices" "os" + "sigs.k8s.io/controller-runtime/pkg/webhook" "strings" // Import all Kubernetes client auth plugins (e.g. Azure, GCP, OIDC, etc.) @@ -123,6 +125,7 @@ func main() { var spireServerAddr string certProvider := CertProviderNone var certManagerIssuer string + var selfSignedCert bool var certManagerUseClusterIssuer bool var useCertManagerApprover bool var secretsManager tls_pod.SecretsManager @@ -135,6 +138,7 @@ func main() { flag.StringVar(&spireServerAddr, "spire-server-address", "spire-server.spire:8081", "SPIRE server API address.") flag.Var(&certProvider, "certificate-provider", fmt.Sprintf("Certificate generation provider (%s)", certProvider.GetPrintableOptionalValues())) flag.StringVar(&certManagerIssuer, "cert-manager-issuer", "ca-issuer", "Name of the Issuer to be used by cert-manager to sign certificates") + flag.BoolVar(&selfSignedCert, "self-signed-cert", true, "Whether to generate and update a self-signed cert for Webhooks") flag.BoolVar(&certManagerUseClusterIssuer, "cert-manager-use-cluster-issuer", false, "Use ClusterIssuer instead of a (namespace bound) Issuer") flag.BoolVar(&useCertManagerApprover, "cert-manager-approve-requests", false, "Make credentials-operator approve its own CertificateRequests") flag.BoolVar(&enableAWSServiceAccountManagement, "enable-aws-serviceaccount-management", false, "Create and bind ServiceAccounts to AWS IAM roles") @@ -161,6 +165,11 @@ func main() { } ctx := ctrl.SetupSignalHandler() + podNamespace := os.Getenv("POD_NAMESPACE") + if podNamespace == "" { + logrus.Fatal("'POD_NAMESPACE' environment variable is required") + os.Exit(1) + } serviceIdResolver := serviceidresolver.NewResolver(mgr.GetClient()) eventRecorder := mgr.GetEventRecorderFor("credentials-operator") @@ -202,17 +211,38 @@ func main() { client := mgr.GetClient() if enableAWSServiceAccountManagement { - awsAgent := awsagent.NewAWSAgent(ctx, awsEksOidcProviderUrl) + awsAgent, err := awsagent.NewAWSAgent(ctx) + if err != nil { + logrus.WithError(err).Error("failed to initialize AWS agent") + } serviceAccountReconciler := serviceaccount.NewServiceAccountReconciler(client, mgr.GetScheme(), awsAgent) if err = serviceAccountReconciler.SetupWithManager(mgr); err != nil { logrus.WithField("controller", "ServiceAccount").WithError(err).Error("unable to create controller") os.Exit(1) } - podServiceAccountReconciler := service_account_pod.NewPodServiceAccountReconciler(client, mgr.GetScheme(), eventRecorder, awsAgent) - if err = podServiceAccountReconciler.SetupWithManager(mgr); err != nil { - logrus.WithField("controller", "Pod").WithError(err).Error("unable to create service account reconciler for pods") - os.Exit(1) + + if selfSignedCert { + logrus.Infoln("Creating self signing certs") + certBundle, err := + operatorwebhooks.GenerateSelfSignedCertificate("credentials-operator-webhook-service", podNamespace) + if err != nil { + logrus.WithError(err).Fatal("unable to create self signed certs for webhook") + } + err = operatorwebhooks.WriteCertToFiles(certBundle) + if err != nil { + logrus.WithError(err).Fatal("failed writing certs to file system") + } + + err = operatorwebhooks.UpdateValidationWebHookCA(context.Background(), + "otterize-credentials-validating-webhook-configuration", certBundle.CertPem) + if err != nil { + logrus.WithError(err).Fatal("updating validation webhook certificate failed") + } } + + podAnnotatorWebhook := webhooks.NewPodWebhookAnnotatesPodServiceAccount(mgr, awsAgent) + mgr.GetWebhookServer().Register("/mutate-v1-pod", &webhook.Admission{Handler: podAnnotatorWebhook}) + } if certProvider != CertProviderNone { From e04cd6f4445242ad5aebcc4346afa8419f078fba Mon Sep 17 00:00:00 2001 From: Ori Shoshan Date: Sat, 18 Nov 2023 16:50:15 +0100 Subject: [PATCH 2/6] Update operator version --- src/operator/go.mod | 7 +++++-- src/operator/go.sum | 7 +++++++ 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/src/operator/go.mod b/src/operator/go.mod index 66fb83f..959cc5c 100644 --- a/src/operator/go.mod +++ b/src/operator/go.mod @@ -9,7 +9,7 @@ require ( github.com/aws/aws-sdk-go-v2/service/iam v1.27.2 github.com/bombsimon/logrusr/v3 v3.0.0 github.com/cert-manager/cert-manager v1.12.3 - github.com/otterize/intents-operator/src v0.0.0-20231029112047-8981c2356ed0 + github.com/otterize/intents-operator/src v0.0.0-20231118154841-80b7a6bca6a6 github.com/pavlo-v-chernykh/keystore-go/v4 v4.4.1 github.com/samber/lo v1.33.0 github.com/sirupsen/logrus v1.9.0 @@ -32,6 +32,9 @@ require ( github.com/Azure/go-ntlmssp v0.0.0-20220621081337-cb9428e4ac1e // indirect github.com/DataDog/datadog-go v3.2.0+incompatible // indirect github.com/Microsoft/go-winio v0.6.0 // indirect + github.com/agnivade/levenshtein v1.1.1 // indirect + github.com/alexflint/go-arg v1.4.2 // indirect + github.com/alexflint/go-scalar v1.0.0 // indirect github.com/armon/go-metrics v0.4.1 // indirect github.com/aws/aws-sdk-go-v2 v1.23.0 // indirect github.com/aws/aws-sdk-go-v2/config v1.25.3 // indirect @@ -137,4 +140,4 @@ require ( sigs.k8s.io/yaml v1.3.0 // indirect ) -replace github.com/otterize/intents-operator/src => ../../../intents-operator/src +//replace github.com/otterize/intents-operator/src => ../../../intents-operator/src diff --git a/src/operator/go.sum b/src/operator/go.sum index 4b3150b..dbf70c9 100644 --- a/src/operator/go.sum +++ b/src/operator/go.sum @@ -49,11 +49,14 @@ github.com/Microsoft/go-winio v0.6.0 h1:slsWYD/zyx7lCXoZVlvQrj0hPTM1HI4+v1sIda2y github.com/Microsoft/go-winio v0.6.0/go.mod h1:cTAf44im0RAYeL23bpB+fzCyDH2MJiz2BO69KH/soAE= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/agnivade/levenshtein v1.0.1/go.mod h1:CURSv5d9Uaml+FovSIICkLbAUZ9S4RqaHDIsdSBg7lM= +github.com/agnivade/levenshtein v1.1.1/go.mod h1:veldBMzWxcCG2ZvUTKD2kJNRdCk5hVbJomOvKkmgYbo= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= +github.com/alexflint/go-arg v1.4.2/go.mod h1:9iRbDxne7LcR/GSvEr7ma++GLpdIU1zrghf2y2768kM= +github.com/alexflint/go-scalar v1.0.0/go.mod h1:GpHzbCOZXEKMEcygYQ5n/aa4Aq84zbxjy3MxYW0gjYw= github.com/amit7itz/goset v1.2.1 h1:usFphDJfZgwnqfbKT8zI+2juuOgsZ6O8UA7NMRUVG7s= github.com/amit7itz/goset v1.2.1/go.mod h1:i8ni2YcxUMAwLBOkHWpy3glFviYdTcWqCvFgp91EMGI= github.com/andres-erbsen/clock v0.0.0-20160526145045-9e14626cd129 h1:MzBOUgng9orim59UnfUTLRjMpd09C5uEVQ6RPGeCaVI= @@ -61,6 +64,7 @@ github.com/andres-erbsen/clock v0.0.0-20160526145045-9e14626cd129/go.mod h1:rFgp github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883 h1:bvNMNQO63//z+xNgfBlViaCIJKLlCJ6/fmUseuG0wVQ= github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8= github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= +github.com/arbovm/levenshtein v0.0.0-20160628152529-48b4e1c0c4d0/go.mod h1:t2tdKJDJF9BV14lnkjHmOQgcvEKgtqs5a1N3LNdJhGE= github.com/armon/go-metrics v0.4.1 h1:hR91U9KYmb6bLBYLQjyM+3j+rcd/UhE+G78SFnF8gJA= github.com/armon/go-metrics v0.4.1/go.mod h1:E6amYzXo6aW1tqzoZGT755KkbgrJsSdpwZ+3JqfkOG4= github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a h1:idn718Q4B6AGu/h5Sxe66HYVdqdGu2l9Iebqhi/AEoA= @@ -136,6 +140,7 @@ github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ3 github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/dgryski/trifles v0.0.0-20200323201526-dd97f9abfb48/go.mod h1:if7Fbed8SFyPtHLHbg49SI7NAdJiC5WIA09pe59rfAA= github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE= github.com/emicklei/go-restful/v3 v3.10.2 h1:hIovbnmBTLjHXkqEBUz3HGpXZdM7ZrE9fJIZIqlJLqE= github.com/emicklei/go-restful/v3 v3.10.2/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= @@ -339,6 +344,8 @@ github.com/onsi/ginkgo/v2 v2.9.5 h1:+6Hr4uxzP4XIUyAkg61dWBw8lb/gc4/X5luuxN/EC+Q= github.com/onsi/ginkgo/v2 v2.9.5/go.mod h1:tvAoo1QUJwNEU2ITftXTpR7R1RbCzoZUOs3RonqW57k= github.com/onsi/gomega v1.27.7 h1:fVih9JD6ogIiHUN6ePK7HJidyEDpWGVB5mzM7cWNXoU= github.com/onsi/gomega v1.27.7/go.mod h1:1p8OOlwo2iUUDsHnOrjE5UKYJ+e3W8eQ3qSlRahPmr4= +github.com/otterize/intents-operator/src v0.0.0-20231118154841-80b7a6bca6a6 h1:wKK4/rHnti6ZND2scbdYqSCSy06FyffhnbkPYliU0/o= +github.com/otterize/intents-operator/src v0.0.0-20231118154841-80b7a6bca6a6/go.mod h1:Hogw74Z2iakq/bwxwDEEPT8fG+rZpiu6Dm7qmMTUBb4= github.com/pascaldekloe/goe v0.1.0 h1:cBOtyMzM9HTpWjXfbbunk26uA6nG3a8n06Wieeh0MwY= github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= github.com/pavlo-v-chernykh/keystore-go/v4 v4.4.1 h1:FyBdsRqqHH4LctMLL+BL2oGO+ONcIPwn96ctofCVtNE= From 6c87873cb5d2dd32458f57a2d370e57979394820 Mon Sep 17 00:00:00 2001 From: Ori Shoshan Date: Sat, 18 Nov 2023 16:53:13 +0100 Subject: [PATCH 3/6] fixup --- src/operator/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/operator/Makefile b/src/operator/Makefile index 8e0ee8f..a126ee2 100644 --- a/src/operator/Makefile +++ b/src/operator/Makefile @@ -93,7 +93,7 @@ manifests: controller-gen ## Generate WebhookConfiguration, ClusterRole and Cust .PHONY: generate generate: controller-gen ## Generate code containing DeepCopy, DeepCopyInto, and DeepCopyObject method implementations. - $(CONTROLLER_GEN) object:headerFile="hack/boilerplate.go.txt" paths="../..." + $(CONTROLLER_GEN) object:headerFile="hack/boilerplate.go.txt" paths="./..." .PHONY: fmt fmt: ## Run go fmt against code. From e1e26ab1798a50cb5a37260a94e7c3f0a5e42253 Mon Sep 17 00:00:00 2001 From: Ori Shoshan Date: Sat, 18 Nov 2023 17:56:42 +0100 Subject: [PATCH 4/6] upgrade intents-operator --- src/operator/go.mod | 2 +- src/operator/go.sum | 7 +++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/src/operator/go.mod b/src/operator/go.mod index 959cc5c..1217770 100644 --- a/src/operator/go.mod +++ b/src/operator/go.mod @@ -9,7 +9,7 @@ require ( github.com/aws/aws-sdk-go-v2/service/iam v1.27.2 github.com/bombsimon/logrusr/v3 v3.0.0 github.com/cert-manager/cert-manager v1.12.3 - github.com/otterize/intents-operator/src v0.0.0-20231118154841-80b7a6bca6a6 + github.com/otterize/intents-operator/src v0.0.0-20231118165400-e986ef885231 github.com/pavlo-v-chernykh/keystore-go/v4 v4.4.1 github.com/samber/lo v1.33.0 github.com/sirupsen/logrus v1.9.0 diff --git a/src/operator/go.sum b/src/operator/go.sum index dbf70c9..52bd2f7 100644 --- a/src/operator/go.sum +++ b/src/operator/go.sum @@ -49,13 +49,16 @@ github.com/Microsoft/go-winio v0.6.0 h1:slsWYD/zyx7lCXoZVlvQrj0hPTM1HI4+v1sIda2y github.com/Microsoft/go-winio v0.6.0/go.mod h1:cTAf44im0RAYeL23bpB+fzCyDH2MJiz2BO69KH/soAE= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/agnivade/levenshtein v1.0.1/go.mod h1:CURSv5d9Uaml+FovSIICkLbAUZ9S4RqaHDIsdSBg7lM= +github.com/agnivade/levenshtein v1.1.1 h1:QY8M92nrzkmr798gCo3kmMyqXFzdQVpxLlGPRBij0P8= github.com/agnivade/levenshtein v1.1.1/go.mod h1:veldBMzWxcCG2ZvUTKD2kJNRdCk5hVbJomOvKkmgYbo= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= +github.com/alexflint/go-arg v1.4.2 h1:lDWZAXxpAnZUq4qwb86p/3rIJJ2Li81EoMbTMujhVa0= github.com/alexflint/go-arg v1.4.2/go.mod h1:9iRbDxne7LcR/GSvEr7ma++GLpdIU1zrghf2y2768kM= +github.com/alexflint/go-scalar v1.0.0 h1:NGupf1XV/Xb04wXskDFzS0KWOLH632W/EO4fAFi+A70= github.com/alexflint/go-scalar v1.0.0/go.mod h1:GpHzbCOZXEKMEcygYQ5n/aa4Aq84zbxjy3MxYW0gjYw= github.com/amit7itz/goset v1.2.1 h1:usFphDJfZgwnqfbKT8zI+2juuOgsZ6O8UA7NMRUVG7s= github.com/amit7itz/goset v1.2.1/go.mod h1:i8ni2YcxUMAwLBOkHWpy3glFviYdTcWqCvFgp91EMGI= @@ -346,6 +349,10 @@ github.com/onsi/gomega v1.27.7 h1:fVih9JD6ogIiHUN6ePK7HJidyEDpWGVB5mzM7cWNXoU= github.com/onsi/gomega v1.27.7/go.mod h1:1p8OOlwo2iUUDsHnOrjE5UKYJ+e3W8eQ3qSlRahPmr4= github.com/otterize/intents-operator/src v0.0.0-20231118154841-80b7a6bca6a6 h1:wKK4/rHnti6ZND2scbdYqSCSy06FyffhnbkPYliU0/o= github.com/otterize/intents-operator/src v0.0.0-20231118154841-80b7a6bca6a6/go.mod h1:Hogw74Z2iakq/bwxwDEEPT8fG+rZpiu6Dm7qmMTUBb4= +github.com/otterize/intents-operator/src v0.0.0-20231118165244-748a655e069d h1:u8n4wWPoqiEdaYWHgJBpLec/yA3QGonVVMB698idEXY= +github.com/otterize/intents-operator/src v0.0.0-20231118165244-748a655e069d/go.mod h1:1V5AvkQodX1eaeZRGCCCSYrG6bN5qRVnUP3UaWAQV3Y= +github.com/otterize/intents-operator/src v0.0.0-20231118165400-e986ef885231 h1:a4QPzUDtM1T0dgNmfPxjVD1D5Mvqj626XdqezMga59M= +github.com/otterize/intents-operator/src v0.0.0-20231118165400-e986ef885231/go.mod h1:1V5AvkQodX1eaeZRGCCCSYrG6bN5qRVnUP3UaWAQV3Y= github.com/pascaldekloe/goe v0.1.0 h1:cBOtyMzM9HTpWjXfbbunk26uA6nG3a8n06Wieeh0MwY= github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= github.com/pavlo-v-chernykh/keystore-go/v4 v4.4.1 h1:FyBdsRqqHH4LctMLL+BL2oGO+ONcIPwn96ctofCVtNE= From 9fd30a9542112d60176d43be59fa08ea7f89723f Mon Sep 17 00:00:00 2001 From: Ori Shoshan Date: Sat, 18 Nov 2023 19:41:54 +0100 Subject: [PATCH 5/6] Make pod webhook actually work --- src/operator/config/rbac/role.yaml | 9 ++++++ .../controllers/metadata/annotations.go | 2 -- src/operator/controllers/metadata/labels.go | 2 ++ .../controllers/webhooks/pod_webhook.go | 32 +++++++++++-------- src/operator/go.mod | 5 +-- src/operator/go.sum | 16 ++-------- src/operator/main.go | 14 +++++--- 7 files changed, 42 insertions(+), 38 deletions(-) diff --git a/src/operator/config/rbac/role.yaml b/src/operator/config/rbac/role.yaml index b3f630e..e76e7fd 100644 --- a/src/operator/config/rbac/role.yaml +++ b/src/operator/config/rbac/role.yaml @@ -27,6 +27,15 @@ rules: - patch - update - watch +- apiGroups: + - admissionregistration.k8s.io + resources: + - mutatingwebhookconfigurations + verbs: + - get + - list + - patch + - update - apiGroups: - apps resources: diff --git a/src/operator/controllers/metadata/annotations.go b/src/operator/controllers/metadata/annotations.go index a9ecb99..6488ffa 100644 --- a/src/operator/controllers/metadata/annotations.go +++ b/src/operator/controllers/metadata/annotations.go @@ -10,8 +10,6 @@ const ( TLSSecretNameAnnotation = "credentials-operator.otterize.com/tls-secret-name" TLSSecretNameAnnotationDeprecated = "spire-integration.otterize.com/tls-secret-name" - // CreateAWSRoleAnnotation by using this annotation a pod marks that the operator should create an AWS IAM role for its service account - CreateAWSRoleAnnotation = "credentials-operator.otterize.com/create-aws-role" // ServiceAccountAWSRoleARNAnnotation is used by EKS (Kubernetes at AWS) to link between service accounts // and IAM roles ServiceAccountAWSRoleARNAnnotation = "eks.amazonaws.com/role-arn" diff --git a/src/operator/controllers/metadata/labels.go b/src/operator/controllers/metadata/labels.go index 16546fe..3314e29 100644 --- a/src/operator/controllers/metadata/labels.go +++ b/src/operator/controllers/metadata/labels.go @@ -13,4 +13,6 @@ const ( // OtterizeServiceAccountLabel is used to label service accounts generated by the credentials-operator OtterizeServiceAccountLabel = "credentials-operator.otterize.com/service-account-managed" + // CreateAWSRoleLabel by using this annotation a pod marks that the operator should create an AWS IAM role for its service account + CreateAWSRoleLabel = "credentials-operator.otterize.com/create-aws-role" ) diff --git a/src/operator/controllers/webhooks/pod_webhook.go b/src/operator/controllers/webhooks/pod_webhook.go index 6c9bdfd..5a27ea6 100644 --- a/src/operator/controllers/webhooks/pod_webhook.go +++ b/src/operator/controllers/webhooks/pod_webhook.go @@ -18,29 +18,30 @@ import ( ) // +kubebuilder:webhook:path=/mutate-v1-pod,mutating=true,failurePolicy=ignore,groups="",sideEffects=NoneOnDryRun,resources=pods,verbs=create;update,versions=v1,admissionReviewVersions=v1,name=pods.credentials-operator.otterize.com +// +kubebuilder:rbac:groups="admissionregistration.k8s.io",resources=mutatingwebhookconfigurations,verbs=get;update;patch;list -type PodWebhookAnnotatesPodServiceAccount struct { +type ServiceAccountAnnotatingPodWebhook struct { client client.Client decoder *admission.Decoder awsAgent *awsagent.Agent } -func NewPodWebhookAnnotatesPodServiceAccount(mgr manager.Manager, awsAgent *awsagent.Agent) *PodWebhookAnnotatesPodServiceAccount { - return &PodWebhookAnnotatesPodServiceAccount{ +func NewServiceAccountAnnotatingPodWebhook(mgr manager.Manager, awsAgent *awsagent.Agent) *ServiceAccountAnnotatingPodWebhook { + return &ServiceAccountAnnotatingPodWebhook{ client: mgr.GetClient(), decoder: admission.NewDecoder(mgr.GetScheme()), awsAgent: awsAgent, } } -func (a *PodWebhookAnnotatesPodServiceAccount) handleOnce(ctx context.Context, pod corev1.Pod, dryRun bool) (outputPod corev1.Pod, patched bool, successMsg string, err error) { - if pod.Annotations == nil { - return pod, false, "no create AWS role annotation - no modifications made", nil +func (a *ServiceAccountAnnotatingPodWebhook) handleOnce(ctx context.Context, pod corev1.Pod, dryRun bool) (outputPod corev1.Pod, patched bool, successMsg string, err error) { + if pod.Labels == nil { + return pod, false, "no create AWS role label - no modifications made", nil } - _, annotationExists := pod.Annotations[metadata.CreateAWSRoleAnnotation] - if !annotationExists { - logrus.Debugf("pod %v doesn't have create AWS IAM role annotation, skipping", pod) - return pod, false, "no create AWS role annotation - no modifications made", nil + _, labelExists := pod.Labels[metadata.CreateAWSRoleLabel] + if !labelExists { + logrus.Debugf("pod %v doesn't have create AWS IAM role label, skipping", pod.Name) + return pod, false, "no create AWS role label - no modifications made", nil } var serviceAccount corev1.ServiceAccount @@ -60,6 +61,10 @@ func (a *PodWebhookAnnotatesPodServiceAccount) handleOnce(ctx context.Context, p updatedServiceAccount.Annotations = make(map[string]string) } + if updatedServiceAccount.Labels == nil { + updatedServiceAccount.Labels = make(map[string]string) + } + // we don't actually create the role here, so that the webhook returns quickly - a ServiceAccount reconciler takes care of it for us. updatedServiceAccount.Annotations[metadata.ServiceAccountAWSRoleARNAnnotation] = roleArn updatedServiceAccount.Labels[metadata.OtterizeServiceAccountLabel] = "true" @@ -70,7 +75,7 @@ func (a *PodWebhookAnnotatesPodServiceAccount) handleOnce(ctx context.Context, p } } - // add label to trigger reinvocation for AWS pod reconciler + // add annotation to trigger reinvocation for AWS pod reconciler if pod.Annotations == nil { pod.Annotations = make(map[string]string) } @@ -80,7 +85,7 @@ func (a *PodWebhookAnnotatesPodServiceAccount) handleOnce(ctx context.Context, p } // dryRun: should not cause any modifications except to the Pod in the request. -func (a *PodWebhookAnnotatesPodServiceAccount) handleWithRetriesOnConflict(ctx context.Context, pod corev1.Pod, dryRun bool) (outputPod corev1.Pod, patched bool, successMsg string, err error) { +func (a *ServiceAccountAnnotatingPodWebhook) handleWithRetriesOnConflict(ctx context.Context, pod corev1.Pod, dryRun bool) (outputPod corev1.Pod, patched bool, successMsg string, err error) { for attempt := 0; attempt < 3; attempt++ { logrus.Debugf("Handling pod '%s' in namespace '%s' (attempt %d out of %d)", pod.Name, pod.Namespace, attempt+1, 3) outputPod, patched, successMsg, err = a.handleOnce(ctx, *pod.DeepCopy(), dryRun) @@ -100,12 +105,13 @@ func (a *PodWebhookAnnotatesPodServiceAccount) handleWithRetriesOnConflict(ctx c panic("unreachable - must have received error or it would have exited in the for loop") } -func (a *PodWebhookAnnotatesPodServiceAccount) Handle(ctx context.Context, req admission.Request) admission.Response { +func (a *ServiceAccountAnnotatingPodWebhook) Handle(ctx context.Context, req admission.Request) admission.Response { pod := corev1.Pod{} err := a.decoder.Decode(req, &pod) if err != nil { return admission.Errored(http.StatusBadRequest, err) } + logrus.Debugf("Got webhook call for pod '%s' in namespace '%s'", pod.Name, pod.Namespace) pod, patched, successMsg, err := a.handleWithRetriesOnConflict(ctx, pod, req.DryRun != nil && *req.DryRun) if err != nil { diff --git a/src/operator/go.mod b/src/operator/go.mod index 1217770..20f8b38 100644 --- a/src/operator/go.mod +++ b/src/operator/go.mod @@ -9,7 +9,7 @@ require ( github.com/aws/aws-sdk-go-v2/service/iam v1.27.2 github.com/bombsimon/logrusr/v3 v3.0.0 github.com/cert-manager/cert-manager v1.12.3 - github.com/otterize/intents-operator/src v0.0.0-20231118165400-e986ef885231 + github.com/otterize/intents-operator/src v0.0.0-20231118174527-3e73c6744e37 github.com/pavlo-v-chernykh/keystore-go/v4 v4.4.1 github.com/samber/lo v1.33.0 github.com/sirupsen/logrus v1.9.0 @@ -32,9 +32,6 @@ require ( github.com/Azure/go-ntlmssp v0.0.0-20220621081337-cb9428e4ac1e // indirect github.com/DataDog/datadog-go v3.2.0+incompatible // indirect github.com/Microsoft/go-winio v0.6.0 // indirect - github.com/agnivade/levenshtein v1.1.1 // indirect - github.com/alexflint/go-arg v1.4.2 // indirect - github.com/alexflint/go-scalar v1.0.0 // indirect github.com/armon/go-metrics v0.4.1 // indirect github.com/aws/aws-sdk-go-v2 v1.23.0 // indirect github.com/aws/aws-sdk-go-v2/config v1.25.3 // indirect diff --git a/src/operator/go.sum b/src/operator/go.sum index 52bd2f7..11fc661 100644 --- a/src/operator/go.sum +++ b/src/operator/go.sum @@ -49,17 +49,11 @@ github.com/Microsoft/go-winio v0.6.0 h1:slsWYD/zyx7lCXoZVlvQrj0hPTM1HI4+v1sIda2y github.com/Microsoft/go-winio v0.6.0/go.mod h1:cTAf44im0RAYeL23bpB+fzCyDH2MJiz2BO69KH/soAE= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/agnivade/levenshtein v1.0.1/go.mod h1:CURSv5d9Uaml+FovSIICkLbAUZ9S4RqaHDIsdSBg7lM= -github.com/agnivade/levenshtein v1.1.1 h1:QY8M92nrzkmr798gCo3kmMyqXFzdQVpxLlGPRBij0P8= -github.com/agnivade/levenshtein v1.1.1/go.mod h1:veldBMzWxcCG2ZvUTKD2kJNRdCk5hVbJomOvKkmgYbo= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= -github.com/alexflint/go-arg v1.4.2 h1:lDWZAXxpAnZUq4qwb86p/3rIJJ2Li81EoMbTMujhVa0= -github.com/alexflint/go-arg v1.4.2/go.mod h1:9iRbDxne7LcR/GSvEr7ma++GLpdIU1zrghf2y2768kM= -github.com/alexflint/go-scalar v1.0.0 h1:NGupf1XV/Xb04wXskDFzS0KWOLH632W/EO4fAFi+A70= -github.com/alexflint/go-scalar v1.0.0/go.mod h1:GpHzbCOZXEKMEcygYQ5n/aa4Aq84zbxjy3MxYW0gjYw= github.com/amit7itz/goset v1.2.1 h1:usFphDJfZgwnqfbKT8zI+2juuOgsZ6O8UA7NMRUVG7s= github.com/amit7itz/goset v1.2.1/go.mod h1:i8ni2YcxUMAwLBOkHWpy3glFviYdTcWqCvFgp91EMGI= github.com/andres-erbsen/clock v0.0.0-20160526145045-9e14626cd129 h1:MzBOUgng9orim59UnfUTLRjMpd09C5uEVQ6RPGeCaVI= @@ -67,7 +61,6 @@ github.com/andres-erbsen/clock v0.0.0-20160526145045-9e14626cd129/go.mod h1:rFgp github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883 h1:bvNMNQO63//z+xNgfBlViaCIJKLlCJ6/fmUseuG0wVQ= github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8= github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= -github.com/arbovm/levenshtein v0.0.0-20160628152529-48b4e1c0c4d0/go.mod h1:t2tdKJDJF9BV14lnkjHmOQgcvEKgtqs5a1N3LNdJhGE= github.com/armon/go-metrics v0.4.1 h1:hR91U9KYmb6bLBYLQjyM+3j+rcd/UhE+G78SFnF8gJA= github.com/armon/go-metrics v0.4.1/go.mod h1:E6amYzXo6aW1tqzoZGT755KkbgrJsSdpwZ+3JqfkOG4= github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a h1:idn718Q4B6AGu/h5Sxe66HYVdqdGu2l9Iebqhi/AEoA= @@ -143,7 +136,6 @@ github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ3 github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/dgryski/trifles v0.0.0-20200323201526-dd97f9abfb48/go.mod h1:if7Fbed8SFyPtHLHbg49SI7NAdJiC5WIA09pe59rfAA= github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE= github.com/emicklei/go-restful/v3 v3.10.2 h1:hIovbnmBTLjHXkqEBUz3HGpXZdM7ZrE9fJIZIqlJLqE= github.com/emicklei/go-restful/v3 v3.10.2/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= @@ -347,12 +339,8 @@ github.com/onsi/ginkgo/v2 v2.9.5 h1:+6Hr4uxzP4XIUyAkg61dWBw8lb/gc4/X5luuxN/EC+Q= github.com/onsi/ginkgo/v2 v2.9.5/go.mod h1:tvAoo1QUJwNEU2ITftXTpR7R1RbCzoZUOs3RonqW57k= github.com/onsi/gomega v1.27.7 h1:fVih9JD6ogIiHUN6ePK7HJidyEDpWGVB5mzM7cWNXoU= github.com/onsi/gomega v1.27.7/go.mod h1:1p8OOlwo2iUUDsHnOrjE5UKYJ+e3W8eQ3qSlRahPmr4= -github.com/otterize/intents-operator/src v0.0.0-20231118154841-80b7a6bca6a6 h1:wKK4/rHnti6ZND2scbdYqSCSy06FyffhnbkPYliU0/o= -github.com/otterize/intents-operator/src v0.0.0-20231118154841-80b7a6bca6a6/go.mod h1:Hogw74Z2iakq/bwxwDEEPT8fG+rZpiu6Dm7qmMTUBb4= -github.com/otterize/intents-operator/src v0.0.0-20231118165244-748a655e069d h1:u8n4wWPoqiEdaYWHgJBpLec/yA3QGonVVMB698idEXY= -github.com/otterize/intents-operator/src v0.0.0-20231118165244-748a655e069d/go.mod h1:1V5AvkQodX1eaeZRGCCCSYrG6bN5qRVnUP3UaWAQV3Y= -github.com/otterize/intents-operator/src v0.0.0-20231118165400-e986ef885231 h1:a4QPzUDtM1T0dgNmfPxjVD1D5Mvqj626XdqezMga59M= -github.com/otterize/intents-operator/src v0.0.0-20231118165400-e986ef885231/go.mod h1:1V5AvkQodX1eaeZRGCCCSYrG6bN5qRVnUP3UaWAQV3Y= +github.com/otterize/intents-operator/src v0.0.0-20231118174527-3e73c6744e37 h1:hhQaTT/thGuB3E3f5Fv2wCfaqk1G9gfirqBmdqc3BUk= +github.com/otterize/intents-operator/src v0.0.0-20231118174527-3e73c6744e37/go.mod h1:1V5AvkQodX1eaeZRGCCCSYrG6bN5qRVnUP3UaWAQV3Y= github.com/pascaldekloe/goe v0.1.0 h1:cBOtyMzM9HTpWjXfbbunk26uA6nG3a8n06Wieeh0MwY= github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= github.com/pavlo-v-chernykh/keystore-go/v4 v4.4.1 h1:FyBdsRqqHH4LctMLL+BL2oGO+ONcIPwn96ctofCVtNE= diff --git a/src/operator/main.go b/src/operator/main.go index 25868ea..e9aa284 100644 --- a/src/operator/main.go +++ b/src/operator/main.go @@ -131,7 +131,7 @@ func main() { var secretsManager tls_pod.SecretsManager var workloadRegistry tls_pod.WorkloadRegistry var enableAWSServiceAccountManagement bool - var awsEksOidcProviderUrl string + var debug bool var userAndPassAcquirer poduserpassword.CloudUserAndPasswordAcquirer flag.StringVar(&metricsAddr, "metrics-bind-address", ":7071", "The address the metric endpoint binds to.") flag.StringVar(&probeAddr, "health-probe-bind-address", ":7072", "The address the probe endpoint binds to.") @@ -142,13 +142,17 @@ func main() { flag.BoolVar(&certManagerUseClusterIssuer, "cert-manager-use-cluster-issuer", false, "Use ClusterIssuer instead of a (namespace bound) Issuer") flag.BoolVar(&useCertManagerApprover, "cert-manager-approve-requests", false, "Make credentials-operator approve its own CertificateRequests") flag.BoolVar(&enableAWSServiceAccountManagement, "enable-aws-serviceaccount-management", false, "Create and bind ServiceAccounts to AWS IAM roles") - flag.StringVar(&awsEksOidcProviderUrl, "eks-oidc-url", "", "EKS OIDC Provider URL") + flag.BoolVar(&debug, "debug", false, "Enable debug logging") flag.BoolVar(&enableLeaderElection, "leader-elect", false, "Enable leader election for controller manager. "+ "Enabling this will ensure there is only one active controller manager.") flag.Parse() + if debug { + logrus.SetLevel(logrus.DebugLevel) + } + ctrl.SetLogger(logrusr.New(logrus.StandardLogger())) mgr, err := ctrl.NewManager(ctrl.GetConfigOrDie(), ctrl.Options{ @@ -233,14 +237,14 @@ func main() { logrus.WithError(err).Fatal("failed writing certs to file system") } - err = operatorwebhooks.UpdateValidationWebHookCA(context.Background(), - "otterize-credentials-validating-webhook-configuration", certBundle.CertPem) + err = operatorwebhooks.UpdateMutationWebHookCA(context.Background(), + "otterize-credentials-operator-mutating-webhook-configuration", certBundle.CertPem) if err != nil { logrus.WithError(err).Fatal("updating validation webhook certificate failed") } } - podAnnotatorWebhook := webhooks.NewPodWebhookAnnotatesPodServiceAccount(mgr, awsAgent) + podAnnotatorWebhook := webhooks.NewServiceAccountAnnotatingPodWebhook(mgr, awsAgent) mgr.GetWebhookServer().Register("/mutate-v1-pod", &webhook.Admission{Handler: podAnnotatorWebhook}) } From 1870e28af4b0877cd43b6600a9d5c11832bc116f Mon Sep 17 00:00:00 2001 From: Ori Shoshan Date: Sun, 19 Nov 2023 22:15:58 +0100 Subject: [PATCH 6/6] upgrade dep --- src/operator/go.mod | 2 +- src/operator/go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/operator/go.mod b/src/operator/go.mod index 20f8b38..b16bb2d 100644 --- a/src/operator/go.mod +++ b/src/operator/go.mod @@ -9,7 +9,7 @@ require ( github.com/aws/aws-sdk-go-v2/service/iam v1.27.2 github.com/bombsimon/logrusr/v3 v3.0.0 github.com/cert-manager/cert-manager v1.12.3 - github.com/otterize/intents-operator/src v0.0.0-20231118174527-3e73c6744e37 + github.com/otterize/intents-operator/src v0.0.0-20231119211508-00d52205eecc github.com/pavlo-v-chernykh/keystore-go/v4 v4.4.1 github.com/samber/lo v1.33.0 github.com/sirupsen/logrus v1.9.0 diff --git a/src/operator/go.sum b/src/operator/go.sum index 11fc661..8ecc2a6 100644 --- a/src/operator/go.sum +++ b/src/operator/go.sum @@ -339,8 +339,8 @@ github.com/onsi/ginkgo/v2 v2.9.5 h1:+6Hr4uxzP4XIUyAkg61dWBw8lb/gc4/X5luuxN/EC+Q= github.com/onsi/ginkgo/v2 v2.9.5/go.mod h1:tvAoo1QUJwNEU2ITftXTpR7R1RbCzoZUOs3RonqW57k= github.com/onsi/gomega v1.27.7 h1:fVih9JD6ogIiHUN6ePK7HJidyEDpWGVB5mzM7cWNXoU= github.com/onsi/gomega v1.27.7/go.mod h1:1p8OOlwo2iUUDsHnOrjE5UKYJ+e3W8eQ3qSlRahPmr4= -github.com/otterize/intents-operator/src v0.0.0-20231118174527-3e73c6744e37 h1:hhQaTT/thGuB3E3f5Fv2wCfaqk1G9gfirqBmdqc3BUk= -github.com/otterize/intents-operator/src v0.0.0-20231118174527-3e73c6744e37/go.mod h1:1V5AvkQodX1eaeZRGCCCSYrG6bN5qRVnUP3UaWAQV3Y= +github.com/otterize/intents-operator/src v0.0.0-20231119211508-00d52205eecc h1:nwUzhSfjuKJrH4O9b840FP/n48Vdf3AT2zbiDr4x56E= +github.com/otterize/intents-operator/src v0.0.0-20231119211508-00d52205eecc/go.mod h1:1V5AvkQodX1eaeZRGCCCSYrG6bN5qRVnUP3UaWAQV3Y= github.com/pascaldekloe/goe v0.1.0 h1:cBOtyMzM9HTpWjXfbbunk26uA6nG3a8n06Wieeh0MwY= github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= github.com/pavlo-v-chernykh/keystore-go/v4 v4.4.1 h1:FyBdsRqqHH4LctMLL+BL2oGO+ONcIPwn96ctofCVtNE=