@@ -13,6 +13,10 @@ import (
13
13
"testing/quick"
14
14
"time"
15
15
16
+ "k8s.io/utils/ptr"
17
+
18
+ controllerclient "github.com/operator-framework/operator-lifecycle-manager/pkg/lib/controller-runtime/client"
19
+
16
20
"github.com/operator-framework/operator-lifecycle-manager/pkg/controller/install"
17
21
18
22
"github.com/sirupsen/logrus"
@@ -837,6 +841,160 @@ func withStatus(catalogSource v1alpha1.CatalogSource, status v1alpha1.CatalogSou
837
841
return copy
838
842
}
839
843
844
+ func TestSyncCatalogSourcesSecurityPolicy (t * testing.T ) {
845
+ assertLegacySecurityPolicy := func (t * testing.T , pod * corev1.Pod ) {
846
+ require .Nil (t , pod .Spec .SecurityContext )
847
+ require .Equal (t , & corev1.SecurityContext {
848
+ ReadOnlyRootFilesystem : ptr .To (false ),
849
+ }, pod .Spec .Containers [0 ].SecurityContext )
850
+ }
851
+
852
+ assertRestrictedPolicy := func (t * testing.T , pod * corev1.Pod ) {
853
+ require .Equal (t , & corev1.PodSecurityContext {
854
+ SeccompProfile : & corev1.SeccompProfile {Type : corev1 .SeccompProfileTypeRuntimeDefault },
855
+ RunAsNonRoot : ptr .To (true ),
856
+ RunAsUser : ptr .To (int64 (1001 )),
857
+ }, pod .Spec .SecurityContext )
858
+ require .Equal (t , & corev1.SecurityContext {
859
+ ReadOnlyRootFilesystem : ptr .To (false ),
860
+ AllowPrivilegeEscalation : ptr .To (false ),
861
+ Capabilities : & corev1.Capabilities {
862
+ Drop : []corev1.Capability {"ALL" },
863
+ },
864
+ }, pod .Spec .Containers [0 ].SecurityContext )
865
+ }
866
+
867
+ clockFake := utilclocktesting .NewFakeClock (time .Date (2018 , time .January , 26 , 20 , 40 , 0 , 0 , time .UTC ))
868
+ tests := []struct {
869
+ testName string
870
+ namespace * corev1.Namespace
871
+ catalogSource * v1alpha1.CatalogSource
872
+ check func (* testing.T , * corev1.Pod )
873
+ }{
874
+ {
875
+ testName : "UnlabeledNamespace/NoUserPreference/LegacySecurityPolicy" ,
876
+ namespace : & corev1.Namespace {
877
+ ObjectMeta : metav1.ObjectMeta {
878
+ Name : "cool-namespace" ,
879
+ },
880
+ },
881
+ catalogSource : & v1alpha1.CatalogSource {
882
+ ObjectMeta : metav1.ObjectMeta {
883
+ Name : "cool-catalog" ,
884
+ Namespace : "cool-namespace" ,
885
+ UID : types .UID ("catalog-uid" ),
886
+ },
887
+ Spec : v1alpha1.CatalogSourceSpec {
888
+ Image : "catalog-image" ,
889
+ SourceType : v1alpha1 .SourceTypeGrpc ,
890
+ },
891
+ },
892
+ check : assertLegacySecurityPolicy ,
893
+ }, {
894
+ testName : "UnlabeledNamespace/UserPreferenceForRestricted/RestrictedSecurityPolicy" ,
895
+ namespace : & corev1.Namespace {
896
+ ObjectMeta : metav1.ObjectMeta {
897
+ Name : "cool-namespace" ,
898
+ },
899
+ },
900
+ catalogSource : & v1alpha1.CatalogSource {
901
+ ObjectMeta : metav1.ObjectMeta {
902
+ Name : "cool-catalog" ,
903
+ Namespace : "cool-namespace" ,
904
+ UID : types .UID ("catalog-uid" ),
905
+ },
906
+ Spec : v1alpha1.CatalogSourceSpec {
907
+ Image : "catalog-image" ,
908
+ SourceType : v1alpha1 .SourceTypeGrpc ,
909
+ GrpcPodConfig : & v1alpha1.GrpcPodConfig {
910
+ SecurityContextConfig : v1alpha1 .Restricted ,
911
+ },
912
+ },
913
+ },
914
+ check : assertRestrictedPolicy ,
915
+ }, {
916
+ testName : "LabeledNamespace/NoUserPreference/RestrictedSecurityPolicy" ,
917
+ namespace : & corev1.Namespace {
918
+ ObjectMeta : metav1.ObjectMeta {
919
+ Name : "cool-namespace" ,
920
+ Labels : map [string ]string {
921
+ // restricted is the default psa policy
922
+ "pod-security.kubernetes.io/enforce" : "restricted" ,
923
+ },
924
+ },
925
+ },
926
+ catalogSource : & v1alpha1.CatalogSource {
927
+ ObjectMeta : metav1.ObjectMeta {
928
+ Name : "cool-catalog" ,
929
+ Namespace : "cool-namespace" ,
930
+ UID : types .UID ("catalog-uid" ),
931
+ },
932
+ Spec : v1alpha1.CatalogSourceSpec {
933
+ Image : "catalog-image" ,
934
+ SourceType : v1alpha1 .SourceTypeGrpc ,
935
+ },
936
+ },
937
+ check : assertRestrictedPolicy ,
938
+ }, {
939
+ testName : "LabeledNamespace/UserPreferenceForLegacy/LegacySecurityPolicy" ,
940
+ namespace : & corev1.Namespace {
941
+ ObjectMeta : metav1.ObjectMeta {
942
+ Name : "cool-namespace" ,
943
+ },
944
+ },
945
+ catalogSource : & v1alpha1.CatalogSource {
946
+ ObjectMeta : metav1.ObjectMeta {
947
+ Name : "cool-catalog" ,
948
+ Namespace : "cool-namespace" ,
949
+ UID : types .UID ("catalog-uid" ),
950
+ },
951
+ Spec : v1alpha1.CatalogSourceSpec {
952
+ Image : "catalog-image" ,
953
+ SourceType : v1alpha1 .SourceTypeGrpc ,
954
+ GrpcPodConfig : & v1alpha1.GrpcPodConfig {
955
+ SecurityContextConfig : v1alpha1 .Legacy ,
956
+ },
957
+ },
958
+ },
959
+ check : assertLegacySecurityPolicy ,
960
+ },
961
+ }
962
+ for _ , tt := range tests {
963
+ t .Run (tt .testName , func (t * testing.T ) {
964
+ // Create existing objects
965
+ clientObjs := []runtime.Object {tt .catalogSource }
966
+
967
+ // Create test operator
968
+ ctx , cancel := context .WithCancel (context .TODO ())
969
+ defer cancel ()
970
+
971
+ op , err := NewFakeOperator (
972
+ ctx ,
973
+ tt .namespace .GetName (),
974
+ []string {tt .namespace .GetName ()},
975
+ withClock (clockFake ),
976
+ withClientObjs (clientObjs ... ),
977
+ )
978
+ require .NoError (t , err )
979
+
980
+ // Because NewFakeOperator creates the namespace, we need to update the namespace to match the test case
981
+ // before running the sync function
982
+ _ , err = op .opClient .KubernetesInterface ().CoreV1 ().Namespaces ().Update (context .TODO (), tt .namespace , metav1.UpdateOptions {})
983
+ require .NoError (t , err )
984
+
985
+ // Run sync
986
+ err = op .syncCatalogSources (tt .catalogSource )
987
+ require .NoError (t , err )
988
+
989
+ pods , err := op .opClient .KubernetesInterface ().CoreV1 ().Pods (tt .catalogSource .Namespace ).List (context .TODO (), metav1.ListOptions {})
990
+ require .NoError (t , err )
991
+ require .Len (t , pods .Items , 1 )
992
+
993
+ tt .check (t , & pods .Items [0 ])
994
+ })
995
+ }
996
+ }
997
+
840
998
func TestSyncCatalogSources (t * testing.T ) {
841
999
clockFake := utilclocktesting .NewFakeClock (time .Date (2018 , time .January , 26 , 20 , 40 , 0 , 0 , time .UTC ))
842
1000
now := metav1 .NewTime (clockFake .Now ())
@@ -1164,7 +1322,7 @@ func TestSyncCatalogSources(t *testing.T) {
1164
1322
if tt .expectedStatus != nil {
1165
1323
if tt .expectedStatus .GRPCConnectionState != nil {
1166
1324
updated .Status .GRPCConnectionState .LastConnectTime = now
1167
- // Ignore LastObservedState difference if an expected LastObservedState is no provided
1325
+ // Ignore LastObservedState difference if an expected LastObservedState is not provided
1168
1326
if tt .expectedStatus .GRPCConnectionState .LastObservedState == "" {
1169
1327
updated .Status .GRPCConnectionState .LastObservedState = ""
1170
1328
}
@@ -2005,15 +2163,13 @@ func NewFakeOperator(ctx context.Context, namespace string, namespaces []string,
2005
2163
}
2006
2164
op .sources = grpc .NewSourceStore (config .logger , 1 * time .Second , 5 * time .Second , op .syncSourceState )
2007
2165
if op .reconciler == nil {
2008
- op .reconciler = & fakes.FakeRegistryReconcilerFactory {
2009
- ReconcilerForSourceStub : func (source * v1alpha1.CatalogSource ) reconciler.RegistryReconciler {
2010
- return & fakes.FakeRegistryReconciler {
2011
- EnsureRegistryServerStub : func (logger * logrus.Entry , source * v1alpha1.CatalogSource ) error {
2012
- return nil
2013
- },
2014
- }
2015
- },
2166
+ s := runtime .NewScheme ()
2167
+ err := k8sfake .AddToScheme (s )
2168
+ if err != nil {
2169
+ return nil , err
2016
2170
}
2171
+ applier := controllerclient .NewFakeApplier (s , "testowner" )
2172
+ op .reconciler = reconciler .NewRegistryReconcilerFactory (lister , op .opClient , "test:pod" , op .now , applier , 1001 , "" , "" )
2017
2173
}
2018
2174
2019
2175
op .RunInformers (ctx )
0 commit comments