Skip to content

Commit

Permalink
feat: support auto generation of ContainerSource identity service acc…
Browse files Browse the repository at this point in the history
…ount and expose in AuthStatus (#7461)

* added serviceaccount in containersource

Signed-off-by: Griffin <prakritimandal611@gmail.com>

* added tests for containersource

Signed-off-by: Griffin <prakritimandal611@gmail.com>

* fixed lint

Signed-off-by: Griffin <prakritimandal611@gmail.com>

* modified tests

Signed-off-by: Griffin <prakritimandal611@gmail.com>

* configured tests

Signed-off-by: Griffin <prakritimandal611@gmail.com>

* fixed lint

Signed-off-by: Griffin <prakritimandal611@gmail.com>

* added tests

Signed-off-by: Griffin <prakritimandal611@gmail.com>

* fixed tests

Signed-off-by: Griffin <prakritimandal611@gmail.com>

---------

Signed-off-by: Griffin <prakritimandal611@gmail.com>
  • Loading branch information
prakrit55 committed Nov 23, 2023
1 parent 46933d0 commit 116abe2
Show file tree
Hide file tree
Showing 7 changed files with 322 additions and 4 deletions.
19 changes: 19 additions & 0 deletions pkg/apis/sources/v1/container_lifecycle.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,14 @@ const (

// ContainerSourceConditionReceiveAdapterReady has status True when the ContainerSource's ReceiveAdapter is ready.
ContainerSourceConditionReceiveAdapterReady apis.ConditionType = "ReceiveAdapterReady"

ContainerConditionOIDCIdentityCreated apis.ConditionType = "OIDCIdentityCreated"
)

var containerCondSet = apis.NewLivingConditionSet(
ContainerSourceConditionSinkBindingReady,
ContainerSourceConditionReceiveAdapterReady,
ContainerConditionOIDCIdentityCreated,
)

// GetConditionSet retrieves the condition set for this resource. Implements the KRShaped interface.
Expand Down Expand Up @@ -63,6 +66,22 @@ func (s *ContainerSourceStatus) InitializeConditions() {
containerCondSet.Manage(s).InitializeConditions()
}

func (s *ContainerSourceStatus) MarkOIDCIdentityCreatedSucceeded() {
containerCondSet.Manage(s).MarkTrue(ContainerConditionOIDCIdentityCreated)
}

func (s *ContainerSourceStatus) MarkOIDCIdentityCreatedSucceededWithReason(reason, messageFormat string, messageA ...interface{}) {
containerCondSet.Manage(s).MarkTrueWithReason(ContainerConditionOIDCIdentityCreated, reason, messageFormat, messageA...)
}

func (s *ContainerSourceStatus) MarkOIDCIdentityCreatedFailed(reason, messageFormat string, messageA ...interface{}) {
containerCondSet.Manage(s).MarkFalse(ContainerConditionOIDCIdentityCreated, reason, messageFormat, messageA...)
}

func (s *ContainerSourceStatus) MarkOIDCIdentityCreatedUnknown(reason, messageFormat string, messageA ...interface{}) {
containerCondSet.Manage(s).MarkUnknown(ContainerConditionOIDCIdentityCreated, reason, messageFormat, messageA...)
}

// PropagateSinkBindingStatus uses the availability of the provided Deployment to determine if
// ContainerSourceConditionSinkBindingReady should be marked as true, false or unknown.
func (s *ContainerSourceStatus) PropagateSinkBindingStatus(status *SinkBindingStatus) {
Expand Down
121 changes: 120 additions & 1 deletion pkg/apis/sources/v1/container_lifecycle_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -104,24 +104,36 @@ func TestContainerSourceStatusIsReady(t *testing.T) {
}(),
wantConditionStatus: corev1.ConditionUnknown,
want: false,
}, {
name: "mark ready sa",
s: func() *ContainerSourceStatus {
s := &ContainerSourceStatus{}
s.InitializeConditions()
s.MarkOIDCIdentityCreatedSucceeded()
return s
}(),
wantConditionStatus: corev1.ConditionUnknown,
want: false,
}, {
name: "mark ready sb and ra",
s: func() *ContainerSourceStatus {
s := &ContainerSourceStatus{}
s.InitializeConditions()
s.PropagateSinkBindingStatus(&readySinkBinding.Status)
s.PropagateReceiveAdapterStatus(availableDeployment)
s.MarkOIDCIdentityCreatedSucceeded()
return s
}(),
wantConditionStatus: corev1.ConditionTrue,
want: true,
}, {
name: "mark ready sb and unavailable ra",
name: "mark ready sb and unavailable ra ",
s: func() *ContainerSourceStatus {
s := &ContainerSourceStatus{}
s.InitializeConditions()
s.PropagateSinkBindingStatus(&readySinkBinding.Status)
s.PropagateReceiveAdapterStatus(unavailableDeployment)
s.MarkOIDCIdentityCreatedSucceeded()
return s
}(),
wantConditionStatus: corev1.ConditionFalse,
Expand All @@ -133,17 +145,55 @@ func TestContainerSourceStatusIsReady(t *testing.T) {
s.InitializeConditions()
s.PropagateSinkBindingStatus(&readySinkBinding.Status)
s.PropagateReceiveAdapterStatus(unknownDeployment)
s.MarkOIDCIdentityCreatedSucceeded()
return s
}(),
wantConditionStatus: corev1.ConditionUnknown,
want: false,
}, {
name: "mark ready sb and ra no sa",
s: func() *ContainerSourceStatus {
s := &ContainerSourceStatus{}
s.InitializeConditions()
s.PropagateSinkBindingStatus(&readySinkBinding.Status)
s.PropagateReceiveAdapterStatus(availableDeployment)
s.MarkOIDCIdentityCreatedFailed("", "")
return s
}(),
wantConditionStatus: corev1.ConditionFalse,
want: false,
}, {
name: "mark ready sb, ra and sa unknown",
s: func() *ContainerSourceStatus {
s := &ContainerSourceStatus{}
s.InitializeConditions()
s.PropagateSinkBindingStatus(&readySinkBinding.Status)
s.PropagateReceiveAdapterStatus(availableDeployment)
s.MarkOIDCIdentityCreatedUnknown("Unknown", "")
return s
}(),
wantConditionStatus: corev1.ConditionUnknown,
want: false,
}, {
name: "mark ready sb, ra and sa with reason",
s: func() *ContainerSourceStatus {
s := &ContainerSourceStatus{}
s.InitializeConditions()
s.PropagateSinkBindingStatus(&readySinkBinding.Status)
s.PropagateReceiveAdapterStatus(availableDeployment)
s.MarkOIDCIdentityCreatedSucceededWithReason("Created", "")
return s
}(),
wantConditionStatus: corev1.ConditionTrue,
want: true,
}, {
name: "mark ready sb and not deployed ra",
s: func() *ContainerSourceStatus {
s := &ContainerSourceStatus{}
s.InitializeConditions()
s.PropagateSinkBindingStatus(&readySinkBinding.Status)
s.PropagateReceiveAdapterStatus(&appsv1.Deployment{})
s.MarkOIDCIdentityCreatedSucceeded()
return s
}(),
wantConditionStatus: corev1.ConditionUnknown,
Expand All @@ -156,6 +206,7 @@ func TestContainerSourceStatusIsReady(t *testing.T) {
s.PropagateSinkBindingStatus(&readySinkBinding.Status)
s.PropagateReceiveAdapterStatus(availableDeployment)
s.PropagateSinkBindingStatus(&notReadySinkBinding.Status)
s.MarkOIDCIdentityCreatedSucceeded()
return s
}(),
wantConditionStatus: corev1.ConditionFalse,
Expand All @@ -168,6 +219,7 @@ func TestContainerSourceStatusIsReady(t *testing.T) {
s.PropagateReceiveAdapterStatus(availableDeployment)
s.PropagateSinkBindingStatus(&notReadySinkBinding.Status)
s.PropagateReceiveAdapterStatus(unavailableDeployment)
s.MarkOIDCIdentityCreatedSucceeded()
return s
}(),
wantConditionStatus: corev1.ConditionFalse,
Expand All @@ -179,6 +231,7 @@ func TestContainerSourceStatusIsReady(t *testing.T) {
s.InitializeConditions()
s.PropagateSinkBindingStatus(&notReadySinkBinding.Status)
s.PropagateReceiveAdapterStatus(availableDeployment)
s.MarkOIDCIdentityCreatedSucceeded()
return s
}(),
wantConditionStatus: corev1.ConditionFalse,
Expand All @@ -191,6 +244,7 @@ func TestContainerSourceStatusIsReady(t *testing.T) {
s.PropagateSinkBindingStatus(&notReadySinkBinding.Status)
s.PropagateReceiveAdapterStatus(availableDeployment)
s.PropagateSinkBindingStatus(&readySinkBinding.Status)
s.MarkOIDCIdentityCreatedSucceeded()
return s
}(),
wantConditionStatus: corev1.ConditionTrue,
Expand All @@ -204,6 +258,7 @@ func TestContainerSourceStatusIsReady(t *testing.T) {
if gotConditionStatus != test.wantConditionStatus {
t.Errorf("unexpected condition status: want %v, got %v", test.wantConditionStatus, gotConditionStatus)
}

}
got := test.s.IsReady()
if got != test.want {
Expand Down Expand Up @@ -262,13 +317,27 @@ func TestContainerSourceStatusGetCondition(t *testing.T) {
Type: ContainerSourceConditionReady,
Status: corev1.ConditionUnknown,
},
}, {
name: "mark ready sa",
s: func() *ContainerSourceStatus {
s := &ContainerSourceStatus{}
s.InitializeConditions()
s.MarkOIDCIdentityCreatedSucceeded()
return s
}(),
condQuery: ContainerSourceConditionReady,
want: &apis.Condition{
Type: ContainerSourceConditionReady,
Status: corev1.ConditionUnknown,
},
}, {
name: "mark ready sb and ra",
s: func() *ContainerSourceStatus {
s := &ContainerSourceStatus{}
s.InitializeConditions()
s.PropagateSinkBindingStatus(&readySinkBinding.Status)
s.PropagateReceiveAdapterStatus(availableDeployment)
s.MarkOIDCIdentityCreatedSucceeded()
return s
}(),
condQuery: ContainerSourceConditionReady,
Expand All @@ -284,6 +353,7 @@ func TestContainerSourceStatusGetCondition(t *testing.T) {
s.PropagateSinkBindingStatus(&readySinkBinding.Status)
s.PropagateReceiveAdapterStatus(availableDeployment)
s.PropagateSinkBindingStatus(&notReadySinkBinding.Status)
s.MarkOIDCIdentityCreatedSucceeded()
return s
}(),
condQuery: ContainerSourceConditionReady,
Expand All @@ -293,6 +363,22 @@ func TestContainerSourceStatusGetCondition(t *testing.T) {
Reason: "Testing",
Message: "hi",
},
}, {
name: "mark ready sb, ra and sa unknown",
s: func() *ContainerSourceStatus {
s := &ContainerSourceStatus{}
s.InitializeConditions()
s.PropagateSinkBindingStatus(&readySinkBinding.Status)
s.PropagateReceiveAdapterStatus(availableDeployment)
s.MarkOIDCIdentityCreatedUnknown("Unknown", "")
return s
}(),
condQuery: ContainerSourceConditionReady,
want: &apis.Condition{
Type: ContainerSourceConditionReady,
Status: corev1.ConditionUnknown,
Reason: "Unknown",
},
}, {
name: "mark ready sb and ra then no ra",
s: func() *ContainerSourceStatus {
Expand All @@ -301,13 +387,45 @@ func TestContainerSourceStatusGetCondition(t *testing.T) {
s.PropagateSinkBindingStatus(&readySinkBinding.Status)
s.PropagateReceiveAdapterStatus(availableDeployment)
s.PropagateReceiveAdapterStatus(unavailableDeployment)
s.MarkOIDCIdentityCreatedSucceeded()
return s
}(),
condQuery: ContainerSourceConditionReady,
want: &apis.Condition{
Type: ContainerSourceConditionReady,
Status: corev1.ConditionFalse,
},
}, {
name: "mark ready sb, sa and ra then no sa",
s: func() *ContainerSourceStatus {
s := &ContainerSourceStatus{}
s.InitializeConditions()
s.PropagateSinkBindingStatus(&readySinkBinding.Status)
s.PropagateReceiveAdapterStatus(availableDeployment)
s.MarkOIDCIdentityCreatedSucceeded()
s.MarkOIDCIdentityCreatedFailed("", "")
return s
}(),
condQuery: ContainerSourceConditionReady,
want: &apis.Condition{
Type: ContainerSourceConditionReady,
Status: corev1.ConditionFalse,
},
}, {
name: "mark ready sb, ra and sa with reason",
s: func() *ContainerSourceStatus {
s := &ContainerSourceStatus{}
s.InitializeConditions()
s.PropagateSinkBindingStatus(&readySinkBinding.Status)
s.PropagateReceiveAdapterStatus(availableDeployment)
s.MarkOIDCIdentityCreatedSucceededWithReason("Created", "")
return s
}(),
condQuery: ContainerSourceConditionReady,
want: &apis.Condition{
Type: ContainerSourceConditionReady,
Status: corev1.ConditionTrue,
},
}, {
name: "mark not ready sb and ready ra then ready sb",
s: func() *ContainerSourceStatus {
Expand All @@ -316,6 +434,7 @@ func TestContainerSourceStatusGetCondition(t *testing.T) {
s.PropagateSinkBindingStatus(&notReadySinkBinding.Status)
s.PropagateReceiveAdapterStatus(availableDeployment)
s.PropagateSinkBindingStatus(&readySinkBinding.Status)
s.MarkOIDCIdentityCreatedSucceeded()
return s
}(),
condQuery: ContainerSourceConditionReady,
Expand Down
24 changes: 23 additions & 1 deletion pkg/reconciler/containersource/containersource.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,15 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/kubernetes"
appsv1listers "k8s.io/client-go/listers/apps/v1"
corev1listers "k8s.io/client-go/listers/core/v1"
"knative.dev/eventing/pkg/apis/feature"
v1 "knative.dev/eventing/pkg/apis/sources/v1"
"knative.dev/eventing/pkg/auth"
clientset "knative.dev/eventing/pkg/client/clientset/versioned"
"knative.dev/eventing/pkg/client/injection/reconciler/sources/v1/containersource"
listers "knative.dev/eventing/pkg/client/listers/sources/v1"
"knative.dev/eventing/pkg/reconciler/containersource/resources"
duckv1 "knative.dev/pkg/apis/duck/v1"
"knative.dev/pkg/controller"
"knative.dev/pkg/logging"
pkgreconciler "knative.dev/pkg/reconciler"
Expand Down Expand Up @@ -62,6 +66,7 @@ type Reconciler struct {
containerSourceLister listers.ContainerSourceLister
sinkBindingLister listers.SinkBindingLister
deploymentLister appsv1listers.DeploymentLister
serviceAccountLister corev1listers.ServiceAccountLister
}

// Check that our Reconciler implements Interface
Expand All @@ -75,6 +80,23 @@ func (r *Reconciler) ReconcileKind(ctx context.Context, source *v1.ContainerSour
return err
}

featureFlags := feature.FromContext(ctx)
if featureFlags.IsOIDCAuthentication() {
saName := auth.GetOIDCServiceAccountNameForResource(v1.SchemeGroupVersion.WithKind("ContainerSource"), source.ObjectMeta)
source.Status.Auth = &duckv1.AuthStatus{
ServiceAccountName: &saName,
}

if err := auth.EnsureOIDCServiceAccountExistsForResource(ctx, r.serviceAccountLister, r.kubeClientSet, v1.SchemeGroupVersion.WithKind("ContainerSource"), source.ObjectMeta); err != nil {
source.Status.MarkOIDCIdentityCreatedFailed("Unable to resolve service account for OIDC authentication", "%v", err)
return err
}
source.Status.MarkOIDCIdentityCreatedSucceeded()
} else {
source.Status.Auth = nil
source.Status.MarkOIDCIdentityCreatedSucceededWithReason(fmt.Sprintf("%s feature disabled", feature.OIDCAuthentication), "")
}

_, err = r.reconcileReceiveAdapter(ctx, source)
if err != nil {
logging.FromContext(ctx).Errorw("Error reconciling ReceiveAdapter", zap.Error(err))
Expand All @@ -98,7 +120,7 @@ func (r *Reconciler) reconcileReceiveAdapter(ctx context.Context, source *v1.Con
} else if err != nil {
return nil, fmt.Errorf("getting Deployment: %v", err)
} else if !metav1.IsControlledBy(ra, source) {
return nil, fmt.Errorf("Deployment %q is not owned by ContainerSource %q", ra.Name, source.Name)
return nil, fmt.Errorf("deployment %q is not owned by ContainerSource %q", ra.Name, source.Name)
} else if r.podSpecChanged(&ra.Spec.Template.Spec, &expected.Spec.Template.Spec) {
ra.Spec.Template.Spec = expected.Spec.Template.Spec
ra, err = r.kubeClientSet.AppsV1().Deployments(expected.Namespace).Update(ctx, ra, metav1.UpdateOptions{})
Expand Down
Loading

0 comments on commit 116abe2

Please sign in to comment.