@@ -711,6 +711,145 @@ func TestFlagdContainerInjector_InjectUnknownSyncProvider(t *testing.T) {
711711 require .ErrorIs (t , err , common .ErrUnrecognizedSyncProvider )
712712}
713713
714+ func TestFlagdContainerInjector_InjectDefaultSyncProvider_Standalone (t * testing.T ) {
715+ namespace , fakeClient := initContainerInjectionTestEnv ()
716+
717+ fi := & FlagdContainerInjector {
718+ Client : fakeClient ,
719+ Logger : testr .New (t ),
720+ FlagdProxyConfig : getProxyConfig (),
721+ FlagdResourceRequirements : getResourceRequirements (),
722+ Image : testImage ,
723+ Tag : testTag ,
724+ }
725+
726+ pod := generatePod (nil , nil , nil , namespace )
727+
728+ flagSourceConfig := getFlagSourceConfigSpec ()
729+
730+ flagSourceConfig .DefaultSyncProvider = apicommon .SyncProviderGrpc
731+
732+ flagSourceConfig .Sources = []api.Source {{}}
733+
734+ err := fi .InjectFlagd (context .Background (), & pod .ObjectMeta , & pod .Spec , flagSourceConfig )
735+ require .Nil (t , err )
736+
737+ expectedPod := getExpectedStandalonePod (namespace )
738+
739+ expectedPod .Spec .Containers [0 ].Args = []string {"start" , "--management-port" , "8014" , "--port" , "8013" , "--sources" , "[{\" uri\" :\" \" ,\" provider\" :\" grpc\" }]" }
740+
741+ require .Equal (t , expectedPod , pod )
742+ }
743+
744+ func TestFlagdContainerInjector_InjectFlagdKubernetesSource_Standalone (t * testing.T ) {
745+ namespace , fakeClient := initContainerInjectionTestEnv ()
746+
747+ fi := & FlagdContainerInjector {
748+ Client : fakeClient ,
749+ Logger : testr .New (t ),
750+ FlagdProxyConfig : getProxyConfig (),
751+ FlagdResourceRequirements : getResourceRequirements (),
752+ Image : testImage ,
753+ Tag : testTag ,
754+ }
755+
756+ pod := generatePod (nil , nil , nil , namespace )
757+
758+ flagSourceConfig := getFlagSourceConfigSpec ()
759+
760+ flagSourceConfig .Sources = []api.Source {
761+ {
762+ Source : "my-namespace/server-side" ,
763+ Provider : apicommon .SyncProviderKubernetes ,
764+ },
765+ }
766+
767+ err := fi .InjectFlagd (context .Background (), & pod .ObjectMeta , & pod .Spec , flagSourceConfig )
768+
769+ require .Nil (t , err )
770+
771+ expectedPod := getExpectedStandalonePod (namespace )
772+
773+ expectedPod .Annotations = map [string ]string {
774+ "openfeature.dev/allowkubernetessync" : "true" ,
775+ }
776+ expectedPod .Spec .Containers [0 ].Args = []string {"start" , "--management-port" , "8014" , "--port" , "8013" , "--sources" , "[{\" uri\" :\" my-namespace/server-side\" ,\" provider\" :\" kubernetes\" }]" }
777+
778+ require .Equal (t , expectedPod , pod )
779+
780+ // verify the update of the ClusterRoleBinding
781+ cbr := & rbacv1.ClusterRoleBinding {}
782+ err = fakeClient .Get (context .Background (), client.ObjectKey {Name : common .ClusterRoleBindingName }, cbr )
783+
784+ require .Nil (t , err )
785+
786+ require .Len (t , cbr .Subjects , 1 )
787+ require .Equal (t , rbacv1.Subject {
788+ Kind : "ServiceAccount" ,
789+ Name : "default" ,
790+ Namespace : namespace ,
791+ }, cbr .Subjects [0 ])
792+ }
793+
794+ func TestFlagdContainerInjector_InjectFlagdFilePathSource_Standalone (t * testing.T ) {
795+ namespace , fakeClient := initContainerInjectionTestEnv ()
796+
797+ fi := & FlagdContainerInjector {
798+ Client : fakeClient ,
799+ Logger : testr .New (t ),
800+ FlagdProxyConfig : getProxyConfig (),
801+ FlagdResourceRequirements : getResourceRequirements (),
802+ Image : testImage ,
803+ Tag : testTag ,
804+ }
805+
806+ pod := generatePod (nil , nil , nil , namespace )
807+
808+ flagSourceConfig := getFlagSourceConfigSpec ()
809+
810+ flagSourceConfig .Sources = []api.Source {
811+ {
812+ Source : "my-namespace/server-side" ,
813+ Provider : apicommon .SyncProviderFilepath ,
814+ },
815+ }
816+
817+ err := fi .InjectFlagd (context .Background (), & pod .ObjectMeta , & pod .Spec , flagSourceConfig )
818+
819+ require .Nil (t , err )
820+
821+ expectedPod := getExpectedStandalonePod (namespace )
822+
823+ expectedPod .Spec .Volumes = []v1.Volume {
824+ {
825+ Name : "server-side" ,
826+ VolumeSource : v1.VolumeSource {
827+ ConfigMap : & v1.ConfigMapVolumeSource {
828+ LocalObjectReference : v1.LocalObjectReference {
829+ Name : "server-side" ,
830+ },
831+ },
832+ },
833+ },
834+ }
835+
836+ expectedPod .Spec .Containers [0 ].Args = []string {"start" , "--management-port" , "8014" , "--port" , "8013" , "--sources" , "[{\" uri\" :\" /etc/flagd/my-namespace_server-side/my-namespace_server-side.flagd.json\" ,\" provider\" :\" file\" }]" }
837+ expectedPod .Spec .Containers [0 ].VolumeMounts = []v1.VolumeMount {
838+ {
839+ Name : "server-side" ,
840+ ReadOnly : false ,
841+ MountPath : "/etc/flagd/my-namespace_server-side" ,
842+ },
843+ }
844+
845+ require .Equal (t , expectedPod , pod )
846+
847+ // verify the creation of the referenced ConfigMap
848+ cm := & v1.ConfigMap {}
849+ err = fakeClient .Get (context .TODO (), client.ObjectKey {Name : pod .Spec .Volumes [0 ].ConfigMap .Name , Namespace : namespace }, cm )
850+ require .Nil (t , err )
851+ }
852+
714853func TestFlagdContainerInjector_createConfigMap (t * testing.T ) {
715854 _ = api .AddToScheme (scheme .Scheme )
716855
@@ -973,6 +1112,101 @@ func getExpectedPod(namespace string) v1.Pod {
9731112 }
9741113}
9751114
1115+ func getExpectedStandalonePod (namespace string ) v1.Pod {
1116+ return v1.Pod {
1117+ ObjectMeta : metav1.ObjectMeta {
1118+ Name : "my-pod" ,
1119+ Namespace : namespace ,
1120+ },
1121+ Spec : v1.PodSpec {
1122+ Containers : []v1.Container {
1123+ {
1124+ Name : "flagd" ,
1125+ Image : "flagd:0.5.0" ,
1126+ WorkingDir : "" ,
1127+ Ports : []v1.ContainerPort {
1128+ {
1129+ Name : "management" ,
1130+ ContainerPort : int32 (8014 ),
1131+ },
1132+ {
1133+ Name : "flagd" ,
1134+ ContainerPort : int32 (8013 ),
1135+ },
1136+ },
1137+ Env : []v1.EnvVar {
1138+ {
1139+ Name : "flagd_my-env-var" ,
1140+ Value : "my-value" ,
1141+ },
1142+ {
1143+ Name : "flagd_MANAGEMENT_PORT" ,
1144+ Value : "8014" ,
1145+ },
1146+ {
1147+ Name : "flagd_PORT" ,
1148+ Value : "8013" ,
1149+ },
1150+ {
1151+ Name : "flagd_EVALUATOR" ,
1152+ Value : "" ,
1153+ },
1154+ {
1155+ Name : "flagd_LOG_FORMAT" ,
1156+ Value : "" ,
1157+ },
1158+ {
1159+ Name : "flagd_RESOLVER" ,
1160+ Value : "rpc" ,
1161+ },
1162+ },
1163+ Resources : getResourceRequirements (),
1164+ LivenessProbe : & v1.Probe {
1165+ ProbeHandler : v1.ProbeHandler {
1166+ HTTPGet : & v1.HTTPGetAction {
1167+ Path : "/healthz" ,
1168+ Port : intstr.IntOrString {Type : 0 , IntVal : 8014 , StrVal : "" },
1169+ Host : "" ,
1170+ Scheme : "HTTP" ,
1171+ },
1172+ },
1173+ InitialDelaySeconds : 5 ,
1174+ },
1175+ ReadinessProbe : & v1.Probe {
1176+ ProbeHandler : v1.ProbeHandler {
1177+ HTTPGet : & v1.HTTPGetAction {
1178+ Path : "/readyz" ,
1179+ Port : intstr.IntOrString {Type : 0 , IntVal : 8014 , StrVal : "" },
1180+ Host : "" ,
1181+ Scheme : "HTTP" ,
1182+ },
1183+ },
1184+ InitialDelaySeconds : 5 ,
1185+ },
1186+ VolumeMounts : []v1.VolumeMount {},
1187+ ImagePullPolicy : "Always" ,
1188+ SecurityContext : & v1.SecurityContext {
1189+ Capabilities : & v1.Capabilities {
1190+ Drop : []v1.Capability {
1191+ "ALL" ,
1192+ },
1193+ },
1194+ Privileged : utils .FalseVal (),
1195+ RunAsUser : intPtr (65532 ),
1196+ RunAsGroup : intPtr (65532 ),
1197+ RunAsNonRoot : utils .TrueVal (),
1198+ ReadOnlyRootFilesystem : utils .TrueVal (),
1199+ AllowPrivilegeEscalation : utils .FalseVal (),
1200+ SeccompProfile : & v1.SeccompProfile {
1201+ Type : "RuntimeDefault" ,
1202+ },
1203+ },
1204+ },
1205+ },
1206+ },
1207+ }
1208+ }
1209+
9761210func generatePod (containers []v1.Container , initContainers []v1.Container , ownerRef []metav1.OwnerReference , ns string ) v1.Pod {
9771211 return v1.Pod {
9781212 ObjectMeta : metav1.ObjectMeta {
0 commit comments