@@ -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,159 @@ 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
+ "pod-security.kubernetes.io/enforce" : "restricted" ,
922
+ },
923
+ },
924
+ },
925
+ catalogSource : & v1alpha1.CatalogSource {
926
+ ObjectMeta : metav1.ObjectMeta {
927
+ Name : "cool-catalog" ,
928
+ Namespace : "cool-namespace" ,
929
+ UID : types .UID ("catalog-uid" ),
930
+ },
931
+ Spec : v1alpha1.CatalogSourceSpec {
932
+ Image : "catalog-image" ,
933
+ SourceType : v1alpha1 .SourceTypeGrpc ,
934
+ },
935
+ },
936
+ check : assertRestrictedPolicy ,
937
+ }, {
938
+ testName : "LabeledNamespace/UserPreferenceForLegacy/LegacySecurityPolicy" ,
939
+ namespace : & corev1.Namespace {
940
+ ObjectMeta : metav1.ObjectMeta {
941
+ Name : "cool-namespace" ,
942
+ },
943
+ },
944
+ catalogSource : & v1alpha1.CatalogSource {
945
+ ObjectMeta : metav1.ObjectMeta {
946
+ Name : "cool-catalog" ,
947
+ Namespace : "cool-namespace" ,
948
+ UID : types .UID ("catalog-uid" ),
949
+ },
950
+ Spec : v1alpha1.CatalogSourceSpec {
951
+ Image : "catalog-image" ,
952
+ SourceType : v1alpha1 .SourceTypeGrpc ,
953
+ GrpcPodConfig : & v1alpha1.GrpcPodConfig {
954
+ SecurityContextConfig : v1alpha1 .Legacy ,
955
+ },
956
+ },
957
+ },
958
+ check : assertLegacySecurityPolicy ,
959
+ },
960
+ }
961
+ for _ , tt := range tests {
962
+ t .Run (tt .testName , func (t * testing.T ) {
963
+ // Create existing objects
964
+ clientObjs := []runtime.Object {tt .catalogSource }
965
+
966
+ // Create test operator
967
+ ctx , cancel := context .WithCancel (context .TODO ())
968
+ defer cancel ()
969
+
970
+ op , err := NewFakeOperator (
971
+ ctx ,
972
+ tt .namespace .GetName (),
973
+ []string {tt .namespace .GetName ()},
974
+ withClock (clockFake ),
975
+ withClientObjs (clientObjs ... ),
976
+ )
977
+ require .NoError (t , err )
978
+
979
+ // Because NewFakeOperator creates the namespace, we need to update the namespace to match the test case
980
+ // before running the sync function
981
+ _ , err = op .opClient .KubernetesInterface ().CoreV1 ().Namespaces ().Update (context .TODO (), tt .namespace , metav1.UpdateOptions {})
982
+ require .NoError (t , err )
983
+
984
+ // Run sync
985
+ err = op .syncCatalogSources (tt .catalogSource )
986
+ require .NoError (t , err )
987
+
988
+ pods , err := op .opClient .KubernetesInterface ().CoreV1 ().Pods (tt .catalogSource .Namespace ).List (context .TODO (), metav1.ListOptions {})
989
+ require .NoError (t , err )
990
+ require .Len (t , pods .Items , 1 )
991
+
992
+ tt .check (t , & pods .Items [0 ])
993
+ })
994
+ }
995
+ }
996
+
840
997
func TestSyncCatalogSources (t * testing.T ) {
841
998
clockFake := utilclocktesting .NewFakeClock (time .Date (2018 , time .January , 26 , 20 , 40 , 0 , 0 , time .UTC ))
842
999
now := metav1 .NewTime (clockFake .Now ())
@@ -1164,7 +1321,7 @@ func TestSyncCatalogSources(t *testing.T) {
1164
1321
if tt .expectedStatus != nil {
1165
1322
if tt .expectedStatus .GRPCConnectionState != nil {
1166
1323
updated .Status .GRPCConnectionState .LastConnectTime = now
1167
- // Ignore LastObservedState difference if an expected LastObservedState is no provided
1324
+ // Ignore LastObservedState difference if an expected LastObservedState is not provided
1168
1325
if tt .expectedStatus .GRPCConnectionState .LastObservedState == "" {
1169
1326
updated .Status .GRPCConnectionState .LastObservedState = ""
1170
1327
}
@@ -2005,15 +2162,13 @@ func NewFakeOperator(ctx context.Context, namespace string, namespaces []string,
2005
2162
}
2006
2163
op .sources = grpc .NewSourceStore (config .logger , 1 * time .Second , 5 * time .Second , op .syncSourceState )
2007
2164
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
- },
2165
+ s := runtime .NewScheme ()
2166
+ err := k8sfake .AddToScheme (s )
2167
+ if err != nil {
2168
+ return nil , err
2016
2169
}
2170
+ applier := controllerclient .NewFakeApplier (s , "testowner" )
2171
+ op .reconciler = reconciler .NewRegistryReconcilerFactory (lister , op .opClient , "test:pod" , op .now , applier , 1001 , "" , "" )
2017
2172
}
2018
2173
2019
2174
op .RunInformers (ctx )
0 commit comments