@@ -34,13 +34,13 @@ type PtrClientObj[T any] interface {
3434// Translator allows to translate back and forth between a CRD schema version
3535// and SDK API structures of a certain version
3636type Translator struct {
37- crd CRDInfo
38- sdk SDKInfo
39- deps DependencyRepo
37+ crd CRDInfo
38+ majorVersion MajorVersion
39+ deps DependencyRepo
4040}
4141
42- // SDKInfo holds the SDK version information
43- type SDKInfo struct {
42+ // MajorVersion holds the SDK version information
43+ type MajorVersion struct {
4444 version string
4545}
4646
@@ -56,13 +56,24 @@ type APIExporter[T any] interface {
5656 ToAPI (t * Translator , target * T ) error
5757}
5858
59- // NewTranslator creates a translator for a particular CRD and SDK version pairs,
60- // and with a particular set of known Kubernetes dependencies
61- func NewTranslator (crd * apiextensionsv1.CustomResourceDefinition , crdVersion string , sdkVersion string , deps DependencyRepo ) * Translator {
59+ // NewTranslator creates a translator for a particular CRD and major version pairs,
60+ // and with a particular set of known Kubernetes object dependencies.
61+ //
62+ // Given the following example resource:
63+ //
64+ // apiVersion: atlas.generated.mongodb.com/v1
65+ // kind: SearchIndex
66+ // metadata:
67+ // name: search-index
68+ // spec:
69+ // v20250312:
70+ //
71+ // In the above case crdVersion is "v1" and majorVersion is "v20250312".
72+ func NewTranslator (crd * apiextensionsv1.CustomResourceDefinition , crdVersion string , majorVersion string , deps DependencyRepo ) * Translator {
6273 return & Translator {
63- crd : CRDInfo {definition : crd , version : crdVersion },
64- sdk : SDKInfo {version : sdkVersion },
65- deps : deps ,
74+ crd : CRDInfo {definition : crd , version : crdVersion },
75+ majorVersion : MajorVersion {version : majorVersion },
76+ deps : deps ,
6677 }
6778}
6879
@@ -81,7 +92,7 @@ func FromAPI[S any, T any, P PtrClientObj[T]](t *Translator, target P, source *S
8192
8293 versionedSpec := map [string ]any {}
8394 copyFields (versionedSpec , sourceUnstructured )
84- if err := createField (targetUnstructured , versionedSpec , "spec" , t .sdk .version ); err != nil {
95+ if err := createField (targetUnstructured , versionedSpec , "spec" , t .majorVersion .version ); err != nil {
8596 return nil , fmt .Errorf ("failed to create versioned spec object in unstructured target: %w" , err )
8697 }
8798 versionedSpecEntry := map [string ]any {}
@@ -90,7 +101,7 @@ func FromAPI[S any, T any, P PtrClientObj[T]](t *Translator, target P, source *S
90101
91102 versionedStatus := map [string ]any {}
92103 copyFields (versionedStatus , sourceUnstructured )
93- if err := createField (targetUnstructured , versionedStatus , "status" , t .sdk .version ); err != nil {
104+ if err := createField (targetUnstructured , versionedStatus , "status" , t .majorVersion .version ); err != nil {
94105 return nil , fmt .Errorf ("failed to create versioned status object in unsstructured target: %w" , err )
95106 }
96107
@@ -120,15 +131,15 @@ func ToAPI[T any](t *Translator, target *T, source client.Object) error {
120131 if err != nil {
121132 return fmt .Errorf ("failed to enumerate CRD spec properties: %w" , err )
122133 }
123- if _ , ok := specProps [t .sdk .version ]; ! ok {
124- return fmt .Errorf ("failed to match the CRD spec version %q in schema" , t .sdk .version )
134+ if _ , ok := specProps [t .majorVersion .version ]; ! ok {
135+ return fmt .Errorf ("failed to match the CRD spec version %q in schema" , t .majorVersion .version )
125136 }
126137 unstructuredSrc , err := toUnstructured (source )
127138 if err != nil {
128139 return fmt .Errorf ("failed to convert k8s source value to unstructured: %w" , err )
129140 }
130141 targetUnstructured := map [string ]any {}
131- value , err := accessField [map [string ]any ](unstructuredSrc , "spec" , t .sdk .version )
142+ value , err := accessField [map [string ]any ](unstructuredSrc , "spec" , t .majorVersion .version )
132143 if err != nil {
133144 return fmt .Errorf ("failed to access source spec value: %w" , err )
134145 }
@@ -175,13 +186,13 @@ func (t *Translator) expandMappings(obj map[string]any) ([]client.Object, error)
175186 return nil , fmt .Errorf ("failed to unmarshal mappings YAML: %w" , err )
176187 }
177188
178- if err := t .expandMappingsAt (obj , mappings , "spec" , t .sdk .version ); err != nil {
189+ if err := t .expandMappingsAt (obj , mappings , "spec" , t .majorVersion .version ); err != nil {
179190 return nil , fmt .Errorf ("failed to map properties of spec from API to Kubernetes: %w" , err )
180191 }
181- if err := t .expandMappingsAt (obj , mappings , "spec" , t .sdk .version , "entry" ); err != nil {
192+ if err := t .expandMappingsAt (obj , mappings , "spec" , t .majorVersion .version , "entry" ); err != nil {
182193 return nil , fmt .Errorf ("failed to map properties of spec from API to Kubernetes: %w" , err )
183194 }
184- if err := t .expandMappingsAt (obj , mappings , "status" , t .sdk .version ); err != nil {
195+ if err := t .expandMappingsAt (obj , mappings , "status" , t .majorVersion .version ); err != nil {
185196 return nil , fmt .Errorf ("failed to map properties of status from API to Kubernetes: %w" , err )
186197 }
187198 return t .deps .Added (), nil
@@ -220,7 +231,7 @@ func (t *Translator) collapseMappings(spec map[string]any) error {
220231 return fmt .Errorf ("failed to unmarshal mappings YAML: %w" , err )
221232 }
222233 props , err := accessField [map [string ]any ](mappings ,
223- "properties" , "spec" , "properties" , t .sdk .version , "properties" )
234+ "properties" , "spec" , "properties" , t .majorVersion .version , "properties" )
224235 if errors .Is (err , ErrNotFound ) {
225236 return nil
226237 }
0 commit comments