@@ -46,16 +46,33 @@ func (src *OpenStackControlPlane) ConvertTo(dstRaw conversion.Hub) error {
4646 return fmt .Errorf ("failed to unmarshal into v1beta2 object: %w" , err )
4747 }
4848
49- // Fix the APIVersion to ensure it's set to v1beta2
50- if dst , ok := dstRaw .(interface { SetAPIVersion (string ) }); ok {
51- dst .SetAPIVersion ("core.openstack.org/v1beta2" )
52- } else {
53- // Use reflection to set the APIVersion field directly
54- dstValue := reflect .ValueOf (dstRaw ).Elem ()
55- if apiVersionField := dstValue .FieldByName ("APIVersion" ); apiVersionField .IsValid () && apiVersionField .CanSet () {
56- apiVersionField .SetString ("core.openstack.org/v1beta2" )
57- }
58- }
49+ // Ensure TypeMeta is set to hub GVK (v1beta2)
50+ dstValue := reflect .ValueOf (dstRaw )
51+ if dstValue .Kind () == reflect .Interface {
52+ dstValue = dstValue .Elem ()
53+ }
54+ if dstValue .Kind () == reflect .Ptr {
55+ dstValue = dstValue .Elem ()
56+ }
57+ if dstValue .IsValid () && dstValue .Kind () == reflect .Struct {
58+ // Prefer setting via embedded TypeMeta if present
59+ if tm := dstValue .FieldByName ("TypeMeta" ); tm .IsValid () && tm .CanSet () && tm .Kind () == reflect .Struct {
60+ if f := tm .FieldByName ("APIVersion" ); f .IsValid () && f .CanSet () {
61+ f .SetString ("core.openstack.org/v1beta2" )
62+ }
63+ if f := tm .FieldByName ("Kind" ); f .IsValid () && f .CanSet () {
64+ f .SetString ("OpenStackControlPlane" )
65+ }
66+ } else {
67+ // Fall back to promoted fields
68+ if f := dstValue .FieldByName ("APIVersion" ); f .IsValid () && f .CanSet () {
69+ f .SetString ("core.openstack.org/v1beta2" )
70+ }
71+ if f := dstValue .FieldByName ("Kind" ); f .IsValid () && f .CanSet () {
72+ f .SetString ("OpenStackControlPlane" )
73+ }
74+ }
75+ }
5976
6077 // Handle Keystone-specific conversions that need special attention
6178 if err := src .convertKeystoneTemplateSpecifics (dstRaw ); err != nil {
@@ -103,9 +120,15 @@ func (src *OpenStackControlPlane) convertKeystoneTemplateSpecifics(dstRaw conver
103120
104121 openstackcontrolplaneconversionlog .V (1 ).Info ("Converting Keystone template from v1beta1 to v1beta2" )
105122
106- // Use reflection to access the v1beta2 keystone template field
107- dstValue := reflect .ValueOf (dstRaw ).Elem ()
108- specField := dstValue .FieldByName ("Spec" )
123+ // Use reflection to access the v1beta2 keystone template field
124+ dstValue := reflect .ValueOf (dstRaw )
125+ if dstValue .Kind () == reflect .Interface {
126+ dstValue = dstValue .Elem ()
127+ }
128+ if dstValue .Kind () == reflect .Ptr {
129+ dstValue = dstValue .Elem ()
130+ }
131+ specField := dstValue .FieldByName ("Spec" )
109132 if ! specField .IsValid () {
110133 return fmt .Errorf ("destination object has no Spec field" )
111134 }
@@ -159,8 +182,14 @@ func (dst *OpenStackControlPlane) convertKeystoneTemplateSpecificsFrom(srcRaw co
159182 openstackcontrolplaneconversionlog .V (1 ).Info ("Converting Keystone template from v1beta2 to v1beta1" )
160183
161184 // Use reflection to access the v1beta2 keystone template field
162- srcValue := reflect .ValueOf (srcRaw ).Elem ()
163- specField := srcValue .FieldByName ("Spec" )
185+ srcValue := reflect .ValueOf (srcRaw )
186+ if srcValue .Kind () == reflect .Interface {
187+ srcValue = srcValue .Elem ()
188+ }
189+ if srcValue .Kind () == reflect .Ptr {
190+ srcValue = srcValue .Elem ()
191+ }
192+ specField := srcValue .FieldByName ("Spec" )
164193 if ! specField .IsValid () {
165194 return fmt .Errorf ("source object has no Spec field" )
166195 }
0 commit comments