@@ -1890,3 +1890,144 @@ func (s *statusWriterMock) Apply(ctx context.Context, obj runtime.ApplyConfigura
18901890 // helps ensure tests fail if this assumption changes
18911891 return fmt .Errorf ("unexpected call to StatusWriter.Apply() - this method is not expected to be used in these tests" )
18921892}
1893+
1894+ func Test_SimpleRevisionGenerator_PodTemplateAnnotationSanitization (t * testing.T ) {
1895+ tests := []struct {
1896+ name string
1897+ podTemplateAnnotations map [string ]string
1898+ expectAnnotationsInRevision bool
1899+ }{
1900+ {
1901+ name : "deployment with non-empty pod template annotations preserves them" ,
1902+ podTemplateAnnotations : map [string ]string {
1903+ "kubectl.kubernetes.io/default-container" : "main" ,
1904+ "prometheus.io/scrape" : "true" ,
1905+ },
1906+ expectAnnotationsInRevision : true ,
1907+ },
1908+ {
1909+ name : "deployment with empty pod template annotations removes them" ,
1910+ podTemplateAnnotations : map [string ]string {},
1911+ expectAnnotationsInRevision : false ,
1912+ },
1913+ {
1914+ name : "deployment with nil pod template annotations has none in revision" ,
1915+ podTemplateAnnotations : nil ,
1916+ expectAnnotationsInRevision : false ,
1917+ },
1918+ }
1919+
1920+ for _ , tt := range tests {
1921+ t .Run (tt .name , func (t * testing.T ) {
1922+ // Create a deployment with specified pod template annotations
1923+ deployment := & appsv1.Deployment {
1924+ ObjectMeta : metav1.ObjectMeta {
1925+ Name : "test-deployment" ,
1926+ },
1927+ Spec : appsv1.DeploymentSpec {
1928+ Replicas : ptr .To (int32 (1 )),
1929+ Selector : & metav1.LabelSelector {
1930+ MatchLabels : map [string ]string {"app" : "test" },
1931+ },
1932+ Template : corev1.PodTemplateSpec {
1933+ ObjectMeta : metav1.ObjectMeta {
1934+ Labels : map [string ]string {"app" : "test" },
1935+ Annotations : tt .podTemplateAnnotations ,
1936+ },
1937+ Spec : corev1.PodSpec {
1938+ Containers : []corev1.Container {
1939+ {
1940+ Name : "main" ,
1941+ Image : "nginx:latest" ,
1942+ },
1943+ },
1944+ },
1945+ },
1946+ },
1947+ }
1948+
1949+ // Create revision generator with fake manifest provider
1950+ scheme := runtime .NewScheme ()
1951+ require .NoError (t , k8scheme .AddToScheme (scheme ))
1952+ require .NoError (t , ocv1 .AddToScheme (scheme ))
1953+
1954+ ext := & ocv1.ClusterExtension {
1955+ ObjectMeta : metav1.ObjectMeta {
1956+ Name : "test-extension" ,
1957+ },
1958+ }
1959+
1960+ manifestProvider := & FakeManifestProvider {
1961+ GetFn : func (_ fs.FS , _ * ocv1.ClusterExtension ) ([]client.Object , error ) {
1962+ return []client.Object {deployment }, nil
1963+ },
1964+ }
1965+
1966+ rg := & applier.SimpleRevisionGenerator {
1967+ Scheme : scheme ,
1968+ ManifestProvider : manifestProvider ,
1969+ }
1970+
1971+ // Create a valid bundle FS
1972+ bundleFS := bundlefs .Builder ().
1973+ WithPackageName ("test-package" ).
1974+ WithCSV (clusterserviceversion .Builder ().WithName ("test-csv" ).Build ()).
1975+ Build ()
1976+
1977+ // Generate revision
1978+ revision , err := rg .GenerateRevision (
1979+ context .Background (),
1980+ bundleFS ,
1981+ ext ,
1982+ map [string ]string {"test" : "label" },
1983+ nil ,
1984+ )
1985+ require .NoError (t , err )
1986+ require .NotNil (t , revision )
1987+
1988+ // Find the deployment in the revision
1989+ var deploymentFound bool
1990+ for _ , obj := range revision .Spec .Phases [0 ].Objects {
1991+ if obj .Object .GetKind () == "Deployment" {
1992+ deploymentFound = true
1993+
1994+ // Check pod template annotations
1995+ spec , ok := obj .Object .Object ["spec" ].(map [string ]any )
1996+ require .True (t , ok , "deployment should have spec" )
1997+
1998+ template , ok := spec ["template" ].(map [string ]any )
1999+ require .True (t , ok , "deployment spec should have template" )
2000+
2001+ templateMeta , ok := template ["metadata" ].(map [string ]any )
2002+ require .True (t , ok , "pod template should have metadata" )
2003+
2004+ annotations , hasAnnotations := templateMeta ["annotations" ]
2005+ if tt .expectAnnotationsInRevision {
2006+ assert .True (t , hasAnnotations , "expected annotations to be present in revision" )
2007+ annotationsMap , ok := annotations .(map [string ]any )
2008+ require .True (t , ok , "annotations should be a map" )
2009+
2010+ for key , expectedValue := range tt .podTemplateAnnotations {
2011+ actualValue , exists := annotationsMap [key ]
2012+ assert .True (t , exists , "expected annotation key %s to exist" , key )
2013+ assert .Equal (t , expectedValue , actualValue , "annotation value mismatch for key %s" , key )
2014+ }
2015+ assert .Len (t , annotationsMap , len (tt .podTemplateAnnotations ), "annotation count mismatch" )
2016+ } else {
2017+ assert .False (t , hasAnnotations , "expected annotations to be removed from revision" )
2018+ }
2019+
2020+ // Labels should always be preserved
2021+ labels , hasLabels := templateMeta ["labels" ]
2022+ assert .True (t , hasLabels , "labels should always be preserved" )
2023+ labelsMap , ok := labels .(map [string ]any )
2024+ require .True (t , ok , "labels should be a map" )
2025+ assert .Equal (t , "test" , labelsMap ["app" ], "label app should be preserved" )
2026+
2027+ break
2028+ }
2029+ }
2030+ assert .True (t , deploymentFound , "deployment should be found in revision" )
2031+ })
2032+ }
2033+ }
0 commit comments